fix merge conflicts

This commit is contained in:
Georg Ehrke 2012-03-03 15:06:51 +01:00
commit f2dcab50b5
128 changed files with 4072 additions and 931 deletions

View file

@ -794,7 +794,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
? 'mysql_query' : 'mysql_unbuffered_query';
$result = @$function($query, $connection);
if (!$result) {
$err =& $this->raiseError(null, null, null,
$err =$this->raiseError(null, null, null,
'Could not execute statement', __FUNCTION__);
return $err;
}

253
3rdparty/phpass/PasswordHash.php vendored Normal file
View file

@ -0,0 +1,253 @@
<?php
#
# Portable PHP password hashing framework.
#
# Version 0.3 / genuine.
#
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
# the public domain. Revised in subsequent years, still public domain.
#
# There's absolutely no warranty.
#
# The homepage URL for this framework is:
#
# http://www.openwall.com/phpass/
#
# Please be sure to update the Version line if you edit this file in any way.
# It is suggested that you leave the main version number intact, but indicate
# your project name (after the slash) and add your own revision information.
#
# Please do not change the "private" password hashing method implemented in
# here, thereby making your hashes incompatible. However, if you must, please
# change the hash type identifier (the "$P$") to something different.
#
# Obviously, since this code is in the public domain, the above are not
# requirements (there can be none), but merely suggestions.
#
class PasswordHash {
var $itoa64;
var $iteration_count_log2;
var $portable_hashes;
var $random_state;
function PasswordHash($iteration_count_log2, $portable_hashes)
{
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
$iteration_count_log2 = 8;
$this->iteration_count_log2 = $iteration_count_log2;
$this->portable_hashes = $portable_hashes;
$this->random_state = microtime();
if (function_exists('getmypid'))
$this->random_state .= getmypid();
}
function get_random_bytes($count)
{
$output = '';
if (is_readable('/dev/urandom') &&
($fh = @fopen('/dev/urandom', 'rb'))) {
$output = fread($fh, $count);
fclose($fh);
}
if (strlen($output) < $count) {
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$this->random_state =
md5(microtime() . $this->random_state);
$output .=
pack('H*', md5($this->random_state));
}
$output = substr($output, 0, $count);
}
return $output;
}
function encode64($input, $count)
{
$output = '';
$i = 0;
do {
$value = ord($input[$i++]);
$output .= $this->itoa64[$value & 0x3f];
if ($i < $count)
$value |= ord($input[$i]) << 8;
$output .= $this->itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count)
break;
if ($i < $count)
$value |= ord($input[$i]) << 16;
$output .= $this->itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count)
break;
$output .= $this->itoa64[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
function gensalt_private($input)
{
$output = '$P$';
$output .= $this->itoa64[min($this->iteration_count_log2 +
((PHP_VERSION >= '5') ? 5 : 3), 30)];
$output .= $this->encode64($input, 6);
return $output;
}
function crypt_private($password, $setting)
{
$output = '*0';
if (substr($setting, 0, 2) == $output)
$output = '*1';
$id = substr($setting, 0, 3);
# We use "$P$", phpBB3 uses "$H$" for the same thing
if ($id != '$P$' && $id != '$H$')
return $output;
$count_log2 = strpos($this->itoa64, $setting[3]);
if ($count_log2 < 7 || $count_log2 > 30)
return $output;
$count = 1 << $count_log2;
$salt = substr($setting, 4, 8);
if (strlen($salt) != 8)
return $output;
# We're kind of forced to use MD5 here since it's the only
# cryptographic primitive available in all versions of PHP
# currently in use. To implement our own low-level crypto
# in PHP would result in much worse performance and
# consequently in lower iteration counts and hashes that are
# quicker to crack (by non-PHP code).
if (PHP_VERSION >= '5') {
$hash = md5($salt . $password, TRUE);
do {
$hash = md5($hash . $password, TRUE);
} while (--$count);
} else {
$hash = pack('H*', md5($salt . $password));
do {
$hash = pack('H*', md5($hash . $password));
} while (--$count);
}
$output = substr($setting, 0, 12);
$output .= $this->encode64($hash, 16);
return $output;
}
function gensalt_extended($input)
{
$count_log2 = min($this->iteration_count_log2 + 8, 24);
# This should be odd to not reveal weak DES keys, and the
# maximum valid value is (2**24 - 1) which is odd anyway.
$count = (1 << $count_log2) - 1;
$output = '_';
$output .= $this->itoa64[$count & 0x3f];
$output .= $this->itoa64[($count >> 6) & 0x3f];
$output .= $this->itoa64[($count >> 12) & 0x3f];
$output .= $this->itoa64[($count >> 18) & 0x3f];
$output .= $this->encode64($input, 3);
return $output;
}
function gensalt_blowfish($input)
{
# This one needs to use a different order of characters and a
# different encoding scheme from the one in encode64() above.
# We care because the last character in our encoded string will
# only represent 2 bits. While two known implementations of
# bcrypt will happily accept and correct a salt string which
# has the 4 unused bits set to non-zero, we do not want to take
# chances and we also do not want to waste an additional byte
# of entropy.
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '$2a$';
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
$output .= '$';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (1);
return $output;
}
function HashPassword($password)
{
$random = '';
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
$random = $this->get_random_bytes(16);
$hash =
crypt($password, $this->gensalt_blowfish($random));
if (strlen($hash) == 60)
return $hash;
}
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
if (strlen($random) < 3)
$random = $this->get_random_bytes(3);
$hash =
crypt($password, $this->gensalt_extended($random));
if (strlen($hash) == 20)
return $hash;
}
if (strlen($random) < 6)
$random = $this->get_random_bytes(6);
$hash =
$this->crypt_private($password,
$this->gensalt_private($random));
if (strlen($hash) == 34)
return $hash;
# Returning '*' on error is safe here, but would _not_ be safe
# in a crypt(3)-like function used _both_ for generating new
# hashes and for validating passwords against existing hashes.
return '*';
}
function CheckPassword($password, $stored_hash)
{
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')
$hash = crypt($password, $stored_hash);
return $hash == $stored_hash;
}
}
?>

21
3rdparty/phpass/c/Makefile vendored Normal file
View file

@ -0,0 +1,21 @@
#
# Written by Solar Designer and placed in the public domain.
# See crypt_private.c for more information.
#
CC = gcc
LD = $(CC)
RM = rm -f
CFLAGS = -Wall -O2 -fomit-frame-pointer -funroll-loops
LDFLAGS = -s
LIBS = -lcrypto
all: crypt_private-test
crypt_private-test: crypt_private-test.o
$(LD) $(LDFLAGS) $(LIBS) crypt_private-test.o -o $@
crypt_private-test.o: crypt_private.c
$(CC) -c $(CFLAGS) crypt_private.c -DTEST -o $@
clean:
$(RM) crypt_private-test*

106
3rdparty/phpass/c/crypt_private.c vendored Normal file
View file

@ -0,0 +1,106 @@
/*
* This code exists for the sole purpose to serve as another implementation
* of the "private" password hashing method implemened in PasswordHash.php
* and thus to confirm that these password hashes are indeed calculated as
* intended.
*
* Other uses of this code are discouraged. There are much better password
* hashing algorithms available to C programmers; one of those is bcrypt:
*
* http://www.openwall.com/crypt/
*
* Written by Solar Designer <solar at openwall.com> in 2005 and placed in
* the public domain.
*
* There's absolutely no warranty.
*/
#include <string.h>
#include <openssl/md5.h>
#ifdef TEST
#include <stdio.h>
#endif
static char *itoa64 =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static void encode64(char *dst, char *src, int count)
{
int i, value;
i = 0;
do {
value = (unsigned char)src[i++];
*dst++ = itoa64[value & 0x3f];
if (i < count)
value |= (unsigned char)src[i] << 8;
*dst++ = itoa64[(value >> 6) & 0x3f];
if (i++ >= count)
break;
if (i < count)
value |= (unsigned char)src[i] << 16;
*dst++ = itoa64[(value >> 12) & 0x3f];
if (i++ >= count)
break;
*dst++ = itoa64[(value >> 18) & 0x3f];
} while (i < count);
}
char *crypt_private(char *password, char *setting)
{
static char output[35];
MD5_CTX ctx;
char hash[MD5_DIGEST_LENGTH];
char *p, *salt;
int count_log2, length, count;
strcpy(output, "*0");
if (!strncmp(setting, output, 2))
output[1] = '1';
if (strncmp(setting, "$P$", 3))
return output;
p = strchr(itoa64, setting[3]);
if (!p)
return output;
count_log2 = p - itoa64;
if (count_log2 < 7 || count_log2 > 30)
return output;
salt = setting + 4;
if (strlen(salt) < 8)
return output;
length = strlen(password);
MD5_Init(&ctx);
MD5_Update(&ctx, salt, 8);
MD5_Update(&ctx, password, length);
MD5_Final(hash, &ctx);
count = 1 << count_log2;
do {
MD5_Init(&ctx);
MD5_Update(&ctx, hash, MD5_DIGEST_LENGTH);
MD5_Update(&ctx, password, length);
MD5_Final(hash, &ctx);
} while (--count);
memcpy(output, setting, 12);
encode64(&output[12], hash, MD5_DIGEST_LENGTH);
return output;
}
#ifdef TEST
int main(int argc, char **argv)
{
if (argc != 3) return 1;
puts(crypt_private(argv[1], argv[2]));
return 0;
}
#endif

72
3rdparty/phpass/test.php vendored Normal file
View file

@ -0,0 +1,72 @@
<?php
#
# This is a test program for the portable PHP password hashing framework.
#
# Written by Solar Designer and placed in the public domain.
# See PasswordHash.php for more information.
#
require 'PasswordHash.php';
header('Content-type: text/plain');
$ok = 0;
# Try to use stronger but system-specific hashes, with a possible fallback to
# the weaker portable hashes.
$t_hasher = new PasswordHash(8, FALSE);
$correct = 'test12345';
$hash = $t_hasher->HashPassword($correct);
print 'Hash: ' . $hash . "\n";
$check = $t_hasher->CheckPassword($correct, $hash);
if ($check) $ok++;
print "Check correct: '" . $check . "' (should be '1')\n";
$wrong = 'test12346';
$check = $t_hasher->CheckPassword($wrong, $hash);
if (!$check) $ok++;
print "Check wrong: '" . $check . "' (should be '0' or '')\n";
unset($t_hasher);
# Force the use of weaker portable hashes.
$t_hasher = new PasswordHash(8, TRUE);
$hash = $t_hasher->HashPassword($correct);
print 'Hash: ' . $hash . "\n";
$check = $t_hasher->CheckPassword($correct, $hash);
if ($check) $ok++;
print "Check correct: '" . $check . "' (should be '1')\n";
$check = $t_hasher->CheckPassword($wrong, $hash);
if (!$check) $ok++;
print "Check wrong: '" . $check . "' (should be '0' or '')\n";
# A correct portable hash for 'test12345'.
# Please note the use of single quotes to ensure that the dollar signs will
# be interpreted literally. Of course, a real application making use of the
# framework won't store password hashes within a PHP source file anyway.
# We only do this for testing.
$hash = '$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0';
print 'Hash: ' . $hash . "\n";
$check = $t_hasher->CheckPassword($correct, $hash);
if ($check) $ok++;
print "Check correct: '" . $check . "' (should be '1')\n";
$check = $t_hasher->CheckPassword($wrong, $hash);
if (!$check) $ok++;
print "Check wrong: '" . $check . "' (should be '0' or '')\n";
if ($ok == 6)
print "All tests have PASSED\n";
else
print "Some tests have FAILED\n";
?>

View file

@ -8,6 +8,7 @@
*/
OC::$CLASSPATH['OC_Bookmarks_Bookmarks'] = 'apps/bookmarks/lib/bookmarks.php';
OC::$CLASSPATH['OC_Search_Provider_Bookmarks'] = 'apps/bookmarks/lib/search.php';
OC_App::register( array( 'order' => 70, 'id' => 'bookmark', 'name' => 'Bookmarks' ));
@ -15,5 +16,5 @@ $l = new OC_l10n('bookmarks');
OC_App::addNavigationEntry( array( 'id' => 'bookmarks_index', 'order' => 70, 'href' => OC_Helper::linkTo( 'bookmarks', 'index.php' ), 'icon' => OC_Helper::imagePath( 'bookmarks', 'bookmarks.png' ), 'name' => $l->t('Bookmarks')));
OC_App::registerPersonal('bookmarks', 'settings');
require_once('apps/bookmarks/lib/search.php');
OC_Util::addScript('bookmarks','bookmarksearch');
OC_Search::registerProvider('OC_Search_Provider_Bookmarks');

View file

@ -17,7 +17,9 @@
}
.bookmarks_list {
margin-top: 36px;
overflow: auto;
position: fixed;
top: 6.5em;
}
.bookmarks_addBml {

View file

@ -5,7 +5,11 @@ var bookmarks_sorting = 'bookmarks_sorting_recent';
$(document).ready(function() {
$('#bookmark_add_submit').click(addOrEditBookmark);
$(window).scroll(updateOnBottom);
$(window).resize(function () {
fillWindow($('.bookmarks_list'));
});
$(window).resize();
$($('.bookmarks_list')).scroll(updateOnBottom);
$('.bookmarks_list').empty();
getBookmarks();
@ -21,7 +25,9 @@ function getBookmarks() {
url: 'ajax/updateList.php',
data: 'tag=' + encodeURI($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
success: function(bookmarks){
bookmarks_page += 1;
if (bookmarks.data.length) {
bookmarks_page += 1;
}
$('.bookmark_link').unbind('click', recordClick);
$('.bookmark_delete').unbind('click', delBookmark);
$('.bookmark_edit').unbind('click', showBookmark);
@ -39,6 +45,9 @@ function getBookmarks() {
$('.bookmark_edit').click(showBookmark);
bookmarks_loading = false;
if (bookmarks.data.length) {
updateOnBottom()
}
}
});
}
@ -146,7 +155,11 @@ function updateBookmarksList(bookmark) {
function updateOnBottom() {
//check wether user is on bottom of the page
if ($('body').height() <= ($(window).height() + $(window).scrollTop())) {
var top = $('.bookmarks_list>:last-child').position().top;
var height = $('.bookmarks_list').height();
// use a bit of margin to begin loading before we are really at the
// bottom
if (top < height * 1.2) {
getBookmarks();
}
}

View file

@ -20,8 +20,8 @@
*
*/
class OC_Search_Provider_Bookmarks extends OC_Search_Provider{
function search($query){
class OC_Search_Provider_Bookmarks implements OC_Search_Provider{
static function search($query){
$results=array();
$offset = 0;
@ -45,6 +45,3 @@ class OC_Search_Provider_Bookmarks extends OC_Search_Provider{
return $results;
}
}
new OC_Search_Provider_Bookmarks();
?>

View file

@ -3,6 +3,6 @@
function createBookmarklet() {
$l = new OC_L10N('bookmarks');
echo '<small>' . $l->t('Drag this to your browser bookmarks and click it, when you want to bookmark a webpage quickly:') . '</small>'
. '<a class="button" href="javascript:(function(){var a=window,b=document,c=encodeURIComponent,d=a.open(\'' . OC_Helper::linkToAbsolute('bookmarks', 'addBm.php') . '?output=popup&url=\'+c(b.location),\'bkmk_popup\',\'left=\'+((a.screenX||a.screenLeft)+10)+\',top=\'+((a.screenY||a.screenTop)+10)+\',height=230px,width=230px,resizable=1,alwaysRaised=1\');a.setTimeout(function(){d.focus()},300);})();">'
. '<a class="bookmarklet" href="javascript:(function(){var a=window,b=document,c=encodeURIComponent,d=a.open(\'' . OC_Helper::linkToAbsolute('bookmarks', 'addBm.php') . '?output=popup&url=\'+c(b.location),\'bkmk_popup\',\'left=\'+((a.screenX||a.screenLeft)+10)+\',top=\'+((a.screenY||a.screenTop)+10)+\',height=230px,width=230px,resizable=1,alwaysRaised=1\');a.setTimeout(function(){d.focus()},300);})();">'
. $l->t('Read later') . '</a>';
}

View file

@ -12,8 +12,13 @@ require_once('../../../3rdparty/when/When.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('calendar');
$start = DateTime::createFromFormat('U', $_GET['start']);
$end = DateTime::createFromFormat('U', $_GET['end']);
if(version_compare(PHP_VERSION, '5.3.0', '>=')){
$start = DateTime::createFromFormat('U', $_GET['start']);
$end = DateTime::createFromFormat('U', $_GET['end']);
}else{
$start = new DateTime('@' . $_GET['start']);
$end = new DateTime('@' . $_GET['end']);
}
if($_GET['calendar_id'] == 'shared_rw' || $_GET['calendar_id'] == 'shared_r'){
$calendars = OC_Calendar_Share::allSharedwithuser(OC_USER::getUser(), OC_Calendar_Share::CALENDAR, 1, ($_GET['calendar_id'] == 'shared_rw')?'rw':'r');
@ -23,28 +28,33 @@ if($_GET['calendar_id'] == 'shared_rw' || $_GET['calendar_id'] == 'shared_r'){
$events = array_merge($events, $calendarevents);
}
}else{
$calendar = OC_Calendar_Calendar::find($_GET['calendar_id']);
if($calendar['userid'] != OC_User::getUser()){
OC_JSON::error();
exit;
$calendar_id = $_GET['calendar_id'];
if (is_numeric($calendar_id)) {
$calendar = OC_Calendar_App::getCalendar($calendar_id);
OC_Response::enableCaching(0);
OC_Response::setETagHeader($calendar['ctag']);
$events = OC_Calendar_Object::allInPeriod($calendar_id, $start, $end);
} else {
$events = array();
OC_Hook::emit('OC_Calendar', 'getEvents', array('calendar_id' => $calendar_id, 'events' => &$events));
}
$events = OC_Calendar_Object::allInPeriod($_GET['calendar_id'], $start, $end);
OC_Response::enableCaching(0);
OC_Response::setETagHeader($calendar['ctag']);
}
$events = OC_Calendar_Object::allInPeriod($_GET['calendar_id'], $start, $end);
$user_timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
$return = array();
foreach($events as $event){
$object = OC_VObject::parse($event['calendardata']);
$vevent = $object->VEVENT;
if (isset($event['calendardata'])) {
$object = OC_VObject::parse($event['calendardata']);
$vevent = $object->VEVENT;
} else {
$vevent = $event['vevent'];
}
$return_event = OC_Calendar_App::prepareForOutput($event, $vevent);
$dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
$start_dt = $dtstart->getDateTime();
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
$end_dt = $dtend->getDateTime();
if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
$return_event['allDay'] = true;

View file

@ -11,7 +11,7 @@ require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
$nl = "\n";
$progressfile = OC::$SERVERROOT . '/apps/calendar/import_tmp/' . md5(session_id()) . '.txt';
$progressfile = OC::$APPSROOT . '/apps/calendar/import_tmp/' . md5(session_id()) . '.txt';
if(is_writable('import_tmp/')){
$progressfopen = fopen($progressfile, 'w');
fwrite($progressfopen, '10');
@ -117,4 +117,4 @@ sleep(3);
if(is_writable('import_tmp/')){
unlink($progressfile);
}
OC_JSON::success();
OC_JSON::success();

View file

@ -0,0 +1,12 @@
<?php
/**
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
$firstday = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'firstday', 'mo');
OC_JSON::encodedPrint(array('firstday' => $firstday));
?>

View file

@ -5,44 +5,23 @@
* later.
* See the COPYING-README file.
*/
function make_array_out_of_xml ($xml){
$returnarray = array();
$xml = (array)$xml ;
foreach ($xml as $property => $value){
$value = (array)$value;
if(!isset($value[0])){
$returnarray[$property] = make_array_out_of_xml($value);
}else{
$returnarray[$property] = trim($value[0]);
}
}
return $returnarray;
}
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('calendar');
$l = new OC_L10N('calendar');
$lat = $_GET['lat'];
$long = $_GET['long'];
if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'position') == $lat . '-' . $long && OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone') != null){
OC_JSON::success();
exit;
}
OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'position', $lat . '-' . $long);
$geolocation = file_get_contents('http://ws.geonames.org/timezone?lat=' . $lat . '&lng=' . $long);
//Information are by Geonames (http://www.geonames.org) and licensed under the Creative Commons Attribution 3.0 License
$geoxml = simplexml_load_string($geolocation);
$geoarray = make_array_out_of_xml($geoxml);
if($geoarray['timezone']['timezoneId'] == OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone')){
OC_JSON::success();
exit;
}
if(in_array($geoarray['timezone']['timezoneId'], DateTimeZone::listIdentifiers())){
OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezone', $geoarray['timezone']['timezoneId']);
$message = array('message'=> $l->t('New Timezone:') . $geoarray['timezone']['timezoneId']);
OC_JSON::success($message);
}else{
OC_JSON::error();
}
?>
$l = new OC_L10N('calendar');
$lat = $_GET['lat'];
$lng = $_GET['long'];
$timezone = OC_Geo::timezone($lat, $lng);
if($timezone == OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone')){
OC_JSON::success();
exit;
}
OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezone', $timezone);
$message = array('message'=> $l->t('New Timezone:') . $timezone);
OC_JSON::success($message);
?>

View file

@ -0,0 +1,17 @@
<?php
/**
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
if(isset($_POST["firstday"])){
OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'firstday', $_POST["firstday"]);
OC_JSON::success();
}else{
OC_JSON::error();
}
?>

View file

@ -1,26 +1,25 @@
<?php
if(version_compare(PHP_VERSION, '5.3.0', '>=')){
$l=new OC_L10N('calendar');
OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
OC_Util::addScript('calendar','loader');
OC_Util::addScript('3rdparty', 'chosen/chosen.jquery.min');
OC_Util::addStyle('3rdparty', 'chosen/chosen');
OC_App::register( array(
'order' => 10,
'id' => 'calendar',
'name' => 'Calendar' ));
OC_App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
'icon' => OC_Helper::imagePath( 'calendar', 'icon.svg' ),
'name' => $l->t('Calendar')));
OC_App::registerPersonal('calendar', 'settings');
require_once('apps/calendar/lib/search.php');
}
$l=new OC_L10N('calendar');
OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
OC_Hook::connect('OC_DAV', 'initialize', 'OC_Calendar_Hooks', 'initializeCalDAV');
OC_Util::addScript('calendar','loader');
OC_App::register( array(
'order' => 10,
'id' => 'calendar',
'name' => 'Calendar' ));
OC_App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
'icon' => OC_Helper::imagePath( 'calendar', 'icon.svg' ),
'name' => $l->t('Calendar')));
OC_App::registerPersonal('calendar', 'settings');
OC_Search::registerProvider('OC_Search_Provider_Calendar');

View file

@ -25,7 +25,7 @@ $nodes = array(
// Fire up server
$server = new Sabre_DAV_Server($nodes);
$server->setBaseUri(OC::$WEBROOT.'/apps/calendar/caldav.php');
$server->setBaseUri(OC::$APPSWEBROOT.'/apps/calendar/caldav.php');
// Add plugins
$server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'));
$server->addPlugin(new Sabre_CalDAV_Plugin());

View file

@ -9,18 +9,24 @@
require_once ('../../lib/base.php');
OC_Util::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
// Create default calendar ...
$calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser(), 1);
if( count($calendars) == 0){
OC_Calendar_Calendar::addCalendar(OC_User::getUser(),'Default calendar');
$calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser(), 1);
}
$eventSources = array();
foreach($calendars as $calendar){
$eventSources[] = OC_Calendar_Calendar::getEventSourceInfo($calendar);
}
$eventSources[] = array('url' => 'ajax/events.php?calendar_id=shared_rw', 'backgroundColor' => '#1D2D44', 'borderColor' => '#888', 'textColor' => 'white', 'editable'=>'true');
$eventSources[] = array('url' => 'ajax/events.php?calendar_id=shared_r', 'backgroundColor' => '#1D2D44', 'borderColor' => '#888', 'textColor' => 'white', 'editable' => 'false');
OC_Hook::emit('OC_Calendar', 'getSources', array('sources' => &$eventSources));
//Fix currentview for fullcalendar
if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'month') == "oneweekview"){
OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", "agendaWeek");

View file

@ -74,6 +74,9 @@ Calendar={
}
},
editEvent:function(calEvent, jsEvent, view){
if (calEvent.editable == false || calEvent.source.editable == false) {
return;
}
var id = calEvent.id;
if($('#event').dialog('isOpen') == true){
// TODO: save event
@ -215,7 +218,7 @@ Calendar={
},
initScroll:function(){
if(window.addEventListener)
document.addEventListener('DOMMouseScroll', Calendar.UI.scrollCalendar);
document.addEventListener('DOMMouseScroll', Calendar.UI.scrollCalendar, false);
//}else{
document.onmousewheel = Calendar.UI.scrollCalendar;
//}
@ -764,7 +767,7 @@ $(document).ready(function(){
Calendar.UI.initScroll();
$('#calendar_holder').fullCalendar({
header: false,
firstDay: 1,
firstDay: firstDay,
editable: true,
defaultView: defaultView,
timeFormat: {

View file

@ -10,7 +10,6 @@ if (navigator.geolocation) {
function(data){
if (data.status == 'success' && typeof(data.message) != 'undefined'){
$('#notification').html(data.message);
$('#notification').attr('title', 'CC BY 3.0 by Geonames.org');
$('#notification').slideDown();
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
}else{

View file

@ -17,6 +17,14 @@ $(document).ready(function(){
}
});
});
$('#firstday').change( function(){
var data = $('#firstday').serialize();
$.post( OC.filePath('calendar', 'ajax/settings', 'setfirstday.php'), data, function(data){
if(data == 'error'){
console.log('saving firstday failed');
}
});
});
$('#timezonedetection').change( function(){
var post = $('#timezonedetection').serialize();
$.post( OC.filePath('calendar', 'ajax/settings', 'timezonedetection.php'), post, function(data){
@ -32,4 +40,8 @@ $(document).ready(function(){
$('#timezonedetection').attr('checked', 'checked');
}
});
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'getfirstday.php'), function(jsondata, status) {
$('#' + jsondata.firstday).attr('selected',true);
$('#firstday').chosen();
});
});

View file

@ -240,9 +240,10 @@ class OC_Calendar_Calendar{
'#9fc6e7', // "light blue"
);
}
public static function getEventSourceInfo($calendar){
return array(
'url' => 'ajax/events.php?calendar_id='.$calendar['id'],
'url' => OC_Helper::linkTo('calendar', 'ajax/events.php').'?calendar_id='.$calendar['id'],
'backgroundColor' => $calendar['calendarcolor'],
'borderColor' => '#888',
'textColor' => 'black',

View file

@ -17,11 +17,24 @@ class OC_Calendar_Hooks{
*/
public static function deleteUser($parameters) {
$calendars = OC_Calendar_Calendar::allCalendars($parameters['uid']);
foreach($calendars as $calendar) {
OC_Calendar_Calendar::deleteCalendar($calendar['id']);
}
return true;
}
/**
* @brief Adds the CardDAV resource to the DAV server
* @param paramters parameters from initialize-Hook
* @return array
*/
public static function initializeCalDAV($parameters){
// We need a backend, the root node and the caldav plugin
$parameters['backends']['caldav'] = new OC_Connector_Sabre_CalDAV();
$parameters['nodes'][] = new Sabre_CalDAV_CalendarRootNode($parameters['backends']['principal'], $parameters['backends']['caldav']);
$parameters['plugins'][] = new Sabre_CalDAV_Plugin();
return true;
}
}

View file

@ -309,6 +309,8 @@ class OC_Calendar_Object{
$dtend = $vevent->DTEND;
}else{
$dtend = clone $vevent->DTSTART;
// clone creates a shallow copy, also clone DateTime
$dtend->setDateTime(clone $dtend->getDateTime(), $dtend->getDateType());
if ($vevent->DURATION){
$duration = strval($vevent->DURATION);
$invert = 0;
@ -817,9 +819,10 @@ class OC_Calendar_Object{
return $vcalendar;
}
public static function getowner($id){
$event = self::find($id);
$cal = OC_Calendar_Calendar::find($event['calendarid']);
return $cal['userid'];
}
}
}

View file

@ -1,6 +1,6 @@
<?php
class OC_Search_Provider_Calendar extends OC_Search_Provider{
function search($query){
class OC_Search_Provider_Calendar implements OC_Search_Provider{
static function search($query){
$calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser(), 1);
if(count($calendars)==0 || !OC_App::isEnabled('calendar')){
//return false;
@ -44,4 +44,3 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
return $results;
}
}
new OC_Search_Provider_Calendar();

View file

@ -19,6 +19,7 @@
var missing_field_startsbeforeends = '<?php echo addslashes($l->t('The event ends before it starts')) ?>';
var missing_field_dberror = '<?php echo addslashes($l->t('There was a database fail')) ?>';
var totalurl = '<?php echo OC_Helper::linkToAbsolute('calendar', 'caldav.php'); ?>/calendars';
var firstDay = '<?php echo (OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'firstday', 'mo') == 'mo' ? '1' : '0'); ?>';
$(document).ready(function() {
<?php
if(array_key_exists('showevent', $_)){

View file

@ -37,6 +37,13 @@
</select>
</td></tr>
<tr><td><label for="firstday" class="bold"><?php echo $l->t('First day of the week');?></label></td><td>
<select style="display: none;" id="firstday" title="<?php echo "First day"; ?>" name="firstday">
<option value="mo" id="mo"><?php echo $l->t("Monday"); ?></option>
<option value="su" id="su"><?php echo $l->t("Sunday"); ?></option>
</select>
</td></tr>
</table>
<?php echo $l->t('Calendar CalDAV syncing address:');?>

View file

@ -4,7 +4,11 @@ OC::$CLASSPATH['OC_Contacts_Addressbook'] = 'apps/contacts/lib/addressbook.php';
OC::$CLASSPATH['OC_Contacts_VCard'] = 'apps/contacts/lib/vcard.php';
OC::$CLASSPATH['OC_Contacts_Hooks'] = 'apps/contacts/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php';
OC::$CLASSPATH['OC_Search_Provider_Contacts'] = 'apps/contacts/lib/search.php';
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Contacts_Hooks', 'deleteUser');
OC_HOOK::connect('OC_Calendar', 'getEvents', 'OC_Contacts_Hooks', 'getBirthdayEvents');
OC_HOOK::connect('OC_Calendar', 'getSources', 'OC_Contacts_Hooks', 'getCalenderSources');
OC_Hook::connect('OC_DAV', 'initialize', 'OC_Contacts_Hooks', 'initializeCardDAV');
OC_App::register( array(
'order' => 10,
@ -21,4 +25,4 @@ OC_App::addNavigationEntry( array(
OC_APP::registerPersonal('contacts','settings');
OC_UTIL::addScript('contacts', 'loader');
require_once('apps/contacts/lib/search.php');
OC_Search::registerProvider('OC_Search_Provider_Contacts');

View file

@ -39,7 +39,7 @@ $nodes = array(
// Fire up server
$server = new Sabre_DAV_Server($nodes);
$server->setBaseUri(OC::$WEBROOT.'/apps/contacts/carddav.php');
$server->setBaseUri(OC::$APPSWEBROOT.'/apps/contacts/carddav.php');
// Add plugins
$server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'));
$server->addPlugin(new Sabre_CardDAV_Plugin());

View file

@ -83,7 +83,7 @@ class OC_Contacts_App {
$vcard = OC_VObject::parse($card['carddata']);
// Try to fix cards with missing 'N' field from pre ownCloud 4. Hot damn, this is ugly...
if(!is_null($vcard) && !$vcard->__isset('N')) {
$appinfo = $info=OC_App::getAppInfo('contacts');
$appinfo = OC_App::getAppInfo('contacts');
if($appinfo['version'] >= 5) {
OC_Log::write('contacts','OC_Contacts_App::getContactVCard. Deprecated check for missing N field', OC_Log::DEBUG);
}

View file

@ -29,7 +29,7 @@ class OC_Contacts_Hooks{
* @param paramters parameters from postDeleteUser-Hook
* @return array
*/
public function deleteUser($parameters) {
static public function deleteUser($parameters) {
$addressbooks = OC_Contacts_Addressbook::all($parameters['uid']);
foreach($addressbooks as $addressbook) {
@ -38,4 +38,62 @@ class OC_Contacts_Hooks{
return true;
}
/**
* @brief Adds the CardDAV resource to the DAV server
* @param paramters parameters from initialize-Hook
* @return array
*/
static public function initializeCardDAV($parameters){
// We need a backend, the root node and the carddav plugin
$parameters['backends']['carddav'] = new OC_Connector_Sabre_CardDAV();
$parameters['nodes'][] = new Sabre_CardDAV_AddressBookRoot($parameters['backends']['principal'], $parameters['backends']['carddav']);
$parameters['plugins'][] = new Sabre_CardDAV_Plugin();
return true;
}
static public function getCalenderSources($parameters) {
$base_url = OC_Helper::linkTo('calendar', 'ajax/events.php').'?calendar_id=';
foreach(OC_Contacts_Addressbook::all(OC_User::getUser()) as $addressbook) {
$parameters['sources'][] =
array(
'url' => $base_url.'birthday_'. $addressbook['id'],
'backgroundColor' => '#cccccc',
'borderColor' => '#888',
'textColor' => 'black',
'cache' => true,
'editable' => false,
);
}
}
static public function getBirthdayEvents($parameters) {
$name = $parameters['calendar_id'];
if (strpos('birthday_', $name) != 0) {
return;
}
$info = explode('_', $name);
$aid = $info[1];
OC_Contacts_App::getAddressbook($aid);
foreach(OC_Contacts_VCard::all($aid) as $card){
$vcard = OC_VObject::parse($card['carddata']);
$birthday = $vcard->BDAY;
if ($birthday) {
$date = new DateTime($birthday);
$vevent = new OC_VObject('VEVENT');
$vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV));
$vevent->setDateTime('DTSTART', $date, Sabre_VObject_Element_DateTime::DATE);
$vevent->setString('DURATION', 'P1D');
// DESCRIPTION?
$vevent->setString('RRULE', 'FREQ=YEARLY');
$title = str_replace('{name}', $vcard->getAsString('FN'), OC_Contacts_App::$l10n->t('{name}\'s Birthday'));
$parameters['events'][] = array(
'id' => 0,//$card['id'],
'vevent' => $vevent,
'repeating' => true,
'summary' => $title,
);
}
}
}
}

View file

@ -1,6 +1,6 @@
<?php
class OC_Search_Provider_Contacts extends OC_Search_Provider{
function search($query){
class OC_Search_Provider_Contacts implements OC_Search_Provider{
static function search($query){
$addressbooks = OC_Contacts_Addressbook::all(OC_User::getUser(), 1);
// if(count($calendars)==0 || !OC_App::isEnabled('contacts')){
// //return false;
@ -26,4 +26,3 @@ class OC_Search_Provider_Contacts extends OC_Search_Provider{
return $results;
}
}
new OC_Search_Provider_Contacts();

View file

@ -0,0 +1,14 @@
<?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.
*/
OC::$CLASSPATH['OC_Archive'] = 'apps/files_archive/lib/archive.php';
foreach(array('ZIP') as $type){
OC::$CLASSPATH['OC_Archive_'.$type] = 'apps/files_archive/lib/'.strtolower($type).'.php';
}
OC::$CLASSPATH['OC_Filestorage_Archive']='apps/files_archive/lib/storage.php';

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>files_archive</id>
<name>Archive support</name>
<description>Transparent opening of archives</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View file

@ -0,0 +1,99 @@
<?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_Archive{
/**
* open any of the supporeted archive types
* @param string path
* @return OC_Archive
*/
public static function open($path){
$ext=substr($path,strrpos($path,'.'));
switch($ext){
case '.zip':
return new OC_Archive_ZIP($path);
}
}
abstract function __construct($source);
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
abstract function addFolder($path);
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
abstract function addFile($path,$source='');
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
abstract function rename($source,$dest);
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
abstract function filesize($path);
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
abstract function mtime($path);
/**
* get the files in a folder
* @param path
* @return array
*/
abstract function getFolder($path);
/**
*get all files in the archive
* @return array
*/
abstract function getFiles();
/**
* get the content of a file
* @param string path
* @return string
*/
abstract function getFile($path);
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
abstract function extractFile($path,$dest);
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
abstract function fileExists($path);
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
abstract function remove($path);
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
abstract function getStream($path,$mode);
}

View file

@ -0,0 +1,102 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Filestorage_Archive extends OC_Filestorage_Common{
/**
* underlying local storage used for missing functions
* @var OC_Archive
*/
private $archive;
private $path;
private function stripPath($path){//files should never start with /
if(substr($path,0,1)=='/'){
return substr($path,1);
}
return $path;
}
public function __construct($params){
$this->archive=OC_Archive::open($params['archive']);
$this->path=$params['archive'];
}
public function mkdir($path){
$path=$this->stripPath($path);
return $this->archive->addFolder($path);
}
public function rmdir($path){
$path=$this->stripPath($path);
return $this->archive->remove($path.'/');
}
public function opendir($path){
$path=$this->stripPath($path);
$content=$this->archive->getFolder($path);
foreach($content as &$file){
if(substr($file,-1)=='/'){
$file=substr($file,0,-1);
}
}
$id=md5($this->path.$path);
OC_FakeDirStream::$dirs[$id]=$content;
return opendir('fakedir://'.$id);
}
public function stat($path){
$ctime=filectime($this->path);
$path=$this->stripPath($path);
if($path==''){
$stat=stat($this->path);
}else{
$stat=array();
$stat['mtime']=$this->archive->mtime($path);
$stat['size']=$this->archive->filesize($path);
}
$stat['ctime']=$ctime;
return $stat;
}
public function filetype($path){
$path=$this->stripPath($path);
if($path==''){
return 'dir';
}
return $this->archive->fileExists($path.'/')?'dir':'file';
}
public function is_readable($path){
return is_readable($this->path);
}
public function is_writable($path){
return is_writable($this->path);
}
public function file_exists($path){
$path=$this->stripPath($path);
if($path==''){
return file_exists($this->path);
}
return $this->archive->fileExists($path) or $this->archive->fileExists($path.'/');
}
public function unlink($path){
$path=$this->stripPath($path);
return $this->archive->remove($path);
}
public function fopen($path,$mode){
$path=$this->stripPath($path);
return $this->archive->getStream($path,$mode);
}
public function free_space($path){
return 0;
}
public function touch($path, $mtime=null){
if(is_null($mtime)){
$tmpFile=OC_Helper::tmpFile();
$this->archive->extractFile($path,$tmpFile);
$this->archive->addfile($path,$tmpFile);
}else{
return false;//not supported
}
}
}

View file

@ -0,0 +1,182 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Archive_ZIP extends OC_Archive{
/**
* @var ZipArchive zip
*/
private $zip=null;
private $contents=array();
private $success=false;
private $path;
function __construct($source){
$this->path=$source;
$this->zip=new ZipArchive();
if($this->zip->open($source,ZipArchive::CREATE)){
}else{
OC_LOG::write('files_archive','Error while opening archive '.$source,OC_Log::WARN);
}
}
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
function addFolder($path){
return $this->zip->addEmptyDir($path);
}
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
function addFile($path,$source=''){
if(file_exists($source)){
$result=$this->zip->addFile($source,$path);
}else{
$result=$this->zip->addFromString($path,$source);
}
if($result){
$this->zip->close();//close and reopen to save the zip
$this->zip->open($this->path);
}
return $result;
}
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
function rename($source,$dest){
return $this->zip->renameName($source,$dest);
}
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
function filesize($path){
$stat=$this->zip->statName($path);
return $stat['size'];
}
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
function mtime($path){
$stat=$this->zip->statName($path);
return $stat['mtime'];
}
/**
* get the files in a folder
* @param path
* @return array
*/
function getFolder($path){
$files=$this->getFiles();
$folderContent=array();
$pathLength=strlen($path);
foreach($files as $file){
if(substr($file,0,$pathLength)==$path and $file!=$path){
if(strrpos(substr($file,0,-1),'/')<=$pathLength){
$folderContent[]=substr($file,$pathLength);
}
}
}
return $folderContent;
}
/**
*get all files in the archive
* @return array
*/
function getFiles(){
if(count($this->contents)){
return $this->contents;
}
$fileCount=$this->zip->numFiles;
$files=array();
for($i=0;$i<$fileCount;$i++){
$files[]=$this->zip->getNameIndex($i);
}
$this->contents=$files;
return $files;
}
/**
* get the content of a file
* @param string path
* @return string
*/
function getFile($path){
return $this->zip->getFromName($path);
}
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
function extractFile($path,$dest){
$fp = $this->zip->getStream($path);
file_put_contents($dest,$fp);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->zip->locateName($path)!==false;
}
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
function remove($path){
return $this->zip->deleteName($path);
}
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
function getStream($path,$mode){
if($mode=='r' or $mode=='rb'){
return $this->zip->getStream($path);
}else{//since we cant directly get a writable stream, make a temp copy of the file and put it back in the archive when the stream is closed
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
if($this->fileExists($path)){
$this->extractFile($path,$tmpFile);
}
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
private static $tempFiles=array();
/**
* write back temporary files
*/
function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->addFile(self::$tempFiles[$tmpFile],$tmpFile);
unlink($tmpFile);
}
}
}

View file

@ -0,0 +1,97 @@
<?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 Test_Archive extends UnitTestCase {
/**
* @var OC_Archive
*/
protected $instance;
/**
* get the existing test archive
* @return OC_Archive
*/
abstract protected function getExisting();
/**
* get a new archive for write testing
* @return OC_Archive
*/
abstract protected function getNew();
public function testGetFiles(){
$this->instance=$this->getExisting();
$allFiles=$this->instance->getFiles();
$expected=array('lorem.txt','logo-wide.png','dir/','dir/lorem.txt');
$this->assertEqual(4,count($allFiles));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$allFiles),'cant find '.$file.' in archive');
$this->assertTrue($this->instance->fileExists($file));
}
$this->assertFalse($this->instance->fileExists('non/existing/file'));
$rootContent=$this->instance->getFolder('');
$expected=array('lorem.txt','logo-wide.png','dir/');
$this->assertEqual(3,count($rootContent));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$rootContent),'cant find '.$file.' in archive');
}
$dirContent=$this->instance->getFolder('dir/');
$expected=array('lorem.txt');
$this->assertEqual(1,count($dirContent));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$dirContent),'cant find '.$file.' in archive');
}
}
public function testContent(){
$this->instance=$this->getExisting();
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$tmpFile=OC_Helper::tmpFile('.txt');
$this->instance->extractFile('lorem.txt',$tmpFile);
$this->assertEqual(file_get_contents($textFile),file_get_contents($tmpFile));
}
public function testWrite(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->instance=$this->getNew();
$this->assertEqual(0,count($this->instance->getFiles()));
$this->instance->addFile('lorem.txt',$textFile);
$this->assertEqual(1,count($this->instance->getFiles()));
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$this->instance->addFile('lorem.txt','foobar');
$this->assertEqual('foobar',$this->instance->getFile('lorem.txt'));
}
public function testReadStream(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getExisting();
$fh=$this->instance->getStream('lorem.txt','r');
$this->assertTrue($fh);
$content=fread($fh,$this->instance->filesize('lorem.txt'));
fclose($fh);
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$content);
}
public function testWriteStream(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getNew();
$fh=$this->instance->getStream('lorem.txt','w');
$source=fopen($dir.'/lorem.txt','r');
OC_Helper::streamCopy($source,$fh);
fclose($source);
fclose($fh);
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$this->instance->getFile('lorem.txt'));
}
}

View file

@ -0,0 +1,25 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class Test_Filestorage_Archive_Zip extends Test_FileStorage {
/**
* @var string tmpDir
*/
private $tmpFile;
public function setUp(){
$this->tmpFile=OC_Helper::tmpFile('.zip');
$this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile));
}
public function tearDown(){
unlink($this->tmpFile);
}
}
?>

View file

@ -0,0 +1,20 @@
<?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('archive.php');
class Test_Archive_ZIP extends Test_Archive{
protected function getExisting(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
return new OC_Archive_ZIP($dir.'/data.zip');
}
protected function getNew(){
return new OC_Archive_ZIP(OC_Helper::tmpFile('.zip'));
}
}

View file

@ -0,0 +1,19 @@
<?php
OC::$CLASSPATH['OC_Crypt'] = 'apps/files_encryption/lib/crypt.php';
OC::$CLASSPATH['OC_CryptStream'] = 'apps/files_encryption/lib/cryptstream.php';
OC::$CLASSPATH['OC_FileProxy_Encryption'] = 'apps/files_encryption/lib/proxy.php';
OC_FileProxy::register(new OC_FileProxy_Encryption());
OC_Hook::connect('OC_User','post_login','OC_Crypt','loginListener');
stream_wrapper_register('crypt','OC_CryptStream');
if(!isset($_SESSION['enckey']) and OC_User::isLoggedIn()){//force the user to re-loggin if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled)
OC_User::logout();
header("Location: ".OC::$WEBROOT.'/');
exit();
}
OC_App::registerAdmin('files_encryption', 'settings');

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>files_encryption</id>
<name>Encryption</name>
<description>Server side encryption of files</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View file

@ -0,0 +1,19 @@
/**
* Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
$(document).ready(function(){
$('#encryption_blacklist').multiSelect({
oncheck:blackListChange,
onuncheck:blackListChange,
createText:'...',
});
function blackListChange(){
var blackList=$('#encryption_blacklist').val().join(',');
OC.AppConfig.setValue('files_encryption','type_blacklist',blackList);
}
})

View file

@ -37,90 +37,111 @@ require_once('Crypt_Blowfish/Blowfish.php');
* This class is for crypting and decrypting
*/
class OC_Crypt {
static private $bf = null;
static $encription_extension='.encrypted';
public static function loginListener($params){
self::init($params['uid'],$params['password']);
}
public static function init($login,$password) {
$_SESSION['user_password'] = $password; // save the password as passcode for the encryption
if(OC_User::isLoggedIn()){
// does key exist?
if(!file_exists(OC_Config::getValue( "datadirectory").'/'.$login.'/encryption.key')){
OC_Crypt::createkey($_SESSION['user_password']);
$view=new OC_FilesystemView('/'.$login);
OC_FileProxy::$enabled=false;
if(!$view->file_exists('/encryption.key')){// does key exist?
OC_Crypt::createkey($login,$password);
}
$key=$view->file_get_contents('/encryption.key');
OC_FileProxy::$enabled=true;
$_SESSION['enckey']=OC_Crypt::decrypt($key, $password);
}
/**
* get the blowfish encryption handeler for a key
* @param string $key (optional)
* @return Crypt_Blowfish
*
* if the key is left out, the default handeler will be used
*/
public static function getBlowfish($key=''){
if($key){
return new Crypt_Blowfish($key);
}else{
if(!isset($_SESSION['enckey'])){
return false;
}
if(!self::$bf){
self::$bf=new Crypt_Blowfish($_SESSION['enckey']);
}
return self::$bf;
}
}
public static function createkey($username,$passcode) {
// generate a random key
$key=mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999);
// encrypt the key with the passcode of the user
$enckey=OC_Crypt::encrypt($key,$passcode);
public static function createkey($passcode) {
if(OC_User::isLoggedIn()){
// generate a random key
$key=mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999);
// encrypt the key with the passcode of the user
$enckey=OC_Crypt::encrypt($key,$passcode);
// Write the file
$username=OC_USER::getUser();
@file_put_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key', $enckey );
}
// Write the file
$proxyEnabled=OC_FileProxy::$enabled;
OC_FileProxy::$enabled=false;
$view=new OC_FilesystemView('/'.$username);
$view->file_put_contents('/encryption.key',$enckey);
OC_FileProxy::$enabled=$proxyEnabled;
}
public static function changekeypasscode( $newpasscode) {
public static function changekeypasscode($oldPassword, $newPassword) {
if(OC_User::isLoggedIn()){
$username=OC_USER::getUser();
$username=OC_USER::getUser();
$view=new OC_FilesystemView('/'.$username);
// read old key
$key=file_get_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key');
$key=$view->file_get_contents('/encryption.key');
// decrypt key with old passcode
$key=OC_Crypt::decrypt($key, $_SESSION['user_password']);
$key=OC_Crypt::decrypt($key, $oldPassword);
// encrypt again with new passcode
$key=OC_Crypt::encrypt($key,$newpassword);
$key=OC_Crypt::encrypt($key, $newPassword);
// store the new key
file_put_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key', $key );
$_SESSION['user_password']=$newpasscode;
$view->file_put_contents('/encryption.key', $key );
}
}
/**
* @brief encrypts an content
* @param $content the cleartext message you want to encrypt
* @param $key the encryption key
* @param $key the encryption key (optional)
* @returns encrypted content
*
* This function encrypts an content
*/
public static function encrypt( $content, $key) {
$bf = new Crypt_Blowfish($key);
public static function encrypt( $content, $key='') {
$bf = self::getBlowfish($key);
return($bf->encrypt($content));
}
/**
* @brief decryption of an content
* @param $content the cleartext message you want to decrypt
* @param $key the encryption key (optional)
* @returns cleartext content
*
* This function decrypts an content
*/
public static function decrypt( $content, $key='') {
$bf = self::getBlowfish($key);
return($bf->decrypt($content));
}
/**
* @brief decryption of an content
* @param $content the cleartext message you want to decrypt
* @param $key the encryption key
* @returns cleartext content
*
* This function decrypts an content
*/
public static function decrypt( $content, $key) {
$bf = new Crypt_Blowfish($key);
return($bf->encrypt($contents));
}
/**
* @brief encryption of a file
* @param $filename
* @param $key the encryption key
*
* This function encrypts a file
*/
/**
* @brief encryption of a file
* @param $filename
* @param $key the encryption key
*
* This function encrypts a file
*/
public static function encryptfile( $filename, $key) {
$handleread = fopen($filename, "rb");
if($handleread<>FALSE) {
@ -158,8 +179,28 @@ class OC_Crypt {
}
fclose($handleread);
}
/**
* encrypt data in 8192b sized blocks
*/
public static function blockEncrypt($data){
$result='';
while(strlen($data)){
$result=self::encrypt(substr($data,0,8192));
$data=substr($data,8192);
}
return $result;
}
/**
* decrypt data in 8192b sized blocks
*/
public static function blockDecrypt($data){
$result='';
while(strlen($data)){
$result=self::decrypt(substr($data,0,8192));
$data=substr($data,8192);
}
return $result;
}
}

View file

@ -0,0 +1,153 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2011 Robin Appelman icewind1991@gmail.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/>.
*
*/
/**
* transparently encrypted filestream
*
* you can use it as wrapper around an existing stream by setting OC_CryptStream::$sourceStreams['foo']=array('path'=>$path,'stream'=>$stream)
* and then fopen('crypt://streams/foo');
*/
class OC_CryptStream{
public static $sourceStreams=array();
private $source;
private $path;
private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream
public function stream_open($path, $mode, $options, &$opened_path){
$path=str_replace('crypt://','',$path);
if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])){
$this->source=self::$sourceStreams[basename($path)]['stream'];
$this->path=self::$sourceStreams[basename($path)]['path'];
}else{
$this->path=$path;
OC_Log::write('files_encryption','open encrypted '.$path. ' in '.$mode,OC_Log::DEBUG);
OC_FileProxy::$enabled=false;//disable fileproxies so we can open the source file
$this->source=OC_FileSystem::fopen($path,$mode);
OC_FileProxy::$enabled=true;
if(!is_resource($this->source)){
OC_Log::write('files_encryption','failed to open '.$path,OC_Log::ERROR);
}
}
if(is_resource($this->source)){
$this->meta=stream_get_meta_data($this->source);
}
return is_resource($this->source);
}
public function stream_seek($offset, $whence=SEEK_SET){
fseek($this->source,$offset,$whence);
}
public function stream_tell(){
return ftell($this->source);
}
public function stream_read($count){
$pos=0;
$currentPos=ftell($this->source);
$offset=$currentPos%8192;
$result='';
if($offset>0){
if($this->meta['seekable']){
fseek($this->source,-$offset,SEEK_CUR);//if seeking isnt supported the internal read buffer will be used
}else{
$pos=strlen($this->readBuffer);
$result=$this->readBuffer;
}
}
while($count>$pos){
$data=fread($this->source,8192);
$pos+=8192;
if(strlen($data)){
$result.=OC_Crypt::decrypt($data);
}
}
if(!$this->meta['seekable']){
$this->readBuffer=substr($result,$count);
}
return substr($result,0,$count);
}
public function stream_write($data){
$length=strlen($data);
$written=0;
$currentPos=ftell($this->source);
if($currentPos%8192!=0){
//make sure we always start on a block start
fseek($this->source,-($currentPos%8192),SEEK_CUR);
$encryptedBlock=fread($this->source,8192);
fseek($this->source,-($currentPos%8192),SEEK_CUR);
$block=OC_Crypt::decrypt($encryptedBlock);
$data=substr($block,0,$currentPos%8192).$data;
}
while(strlen($data)>0){
if(strlen($data)<8192){
//fetch the current data in that block and append it to the input so we always write entire blocks
$oldPos=ftell($this->source);
$encryptedBlock=fread($this->source,8192);
fseek($this->source,$oldPos);
$block=OC_Crypt::decrypt($encryptedBlock);
$data.=substr($block,strlen($data));
}
$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted);
$data=substr($data,8192);
}
return $length;
}
public function stream_set_option($option,$arg1,$arg2){
switch($option){
case STREAM_OPTION_BLOCKING:
stream_set_blocking($this->source,$arg1);
break;
case STREAM_OPTION_READ_TIMEOUT:
stream_set_timeout($this->source,$arg1,$arg2);
break;
case STREAM_OPTION_WRITE_BUFFER:
stream_set_write_buffer($this->source,$arg1,$arg2);
}
}
public function stream_stat(){
return fstat($this->source);
}
public function stream_lock($mode){
flock($this->source,$mode);
}
public function stream_flush(){
return fflush($this->source);
}
public function stream_eof(){
return feof($this->source);
}
public function stream_close(){
OC_FileCache::put($this->path,array('encrypted'=>true));
return fclose($this->source);
}
}

View file

@ -0,0 +1,115 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2011 Robin Appelman icewind1991@gmail.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/>.
*
*/
/**
* transparent encryption
*/
class OC_FileProxy_Encryption extends OC_FileProxy{
private static $blackList=null; //mimetypes blacklisted from encryption
private static $metaData=array(); //metadata cache
/**
* check if a file should be encrypted during write
* @param string $path
* @return bool
*/
private static function shouldEncrypt($path){
if(is_null(self::$blackList)){
self::$blackList=explode(',',OC_Appconfig::getValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg'));
}
if(self::isEncrypted($path)){
return true;
}
$extention=substr($path,strrpos($path,'.')+1);
if(array_search($extention,self::$blackList)===false){
return true;
}
}
/**
* check if a file is encrypted
* @param string $path
* @return bool
*/
private static function isEncrypted($path){
if(isset(self::$metaData[$path])){
$metadata=self::$metaData[$path];
}else{
$metadata=OC_FileCache::getCached($path);
self::$metaData[$path]=$metadata;
}
return (bool)$metadata['encrypted'];
}
public function preFile_put_contents($path,&$data){
if(self::shouldEncrypt($path)){
if (!is_resource($data)) {//stream put contents should have been converter to fopen
$data=OC_Crypt::blockEncrypt($data);
OC_FileCache::put($path,array('encrypted'=>true));
}
}
}
public function postFile_get_contents($path,$data){
if(self::isEncrypted($path)){
$data=OC_Crypt::blockDecrypt($data);
}
return $data;
}
public function postFopen($path,&$result){
if(!$result){
return $result;
}
$meta=stream_get_meta_data($result);
if(self::isEncrypted($path)){
fclose($result);
$result=fopen('crypt://'.$path,$meta['mode']);
}elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb'){
if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0){
//first encrypt the target file so we don't end up with a half encrypted file
OC_Log::write('files_encryption','Decrypting '.$path.' before writing',OC_Log::DEBUG);
$tmp=fopen('php://temp');
while(!feof($result)){
$chunk=fread($result,8192);
if($chunk){
fwrite($tmp,$chunk);
}
}
fclose($result);
OC_Filesystem::file_put_contents($path,$tmp);
fclose($tmp);
}
$result=fopen('crypt://'.$path,$meta['mode']);
}
return $result;
}
public function postGetMimeType($path,$mime){
if(self::isEncrypted($path)){
$mime=OC_Helper::getMimeType('crypt://'.$path,'w');
}
return $mime;
}
}

View file

@ -0,0 +1,16 @@
<?php
/**
* Copyright (c) 2011 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
$tmpl = new OC_Template( 'files_encryption', 'settings');
$blackList=explode(',',OC_Appconfig::getValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg'));
$tmpl->assign('blacklist',$blackList);
OC_Util::addScript('files_encryption','settings');
OC_Util::addScript('core','multiselect');
return $tmpl->fetchPage();

View file

@ -0,0 +1,11 @@
<form id="calendar">
<fieldset class="personalblock">
<strong><?php echo $l->t('Encryption'); ?></strong>
<?php echo $l->t("Exclude the following file types from encryption"); ?>
<select id='encryption_blacklist' title="<?php echo $l->t('None')?>" multiple="multiple">
<?php foreach($_["blacklist"] as $type): ?>
<option selected="selected" value="<?php echo $type;?>"><?php echo $type;?></option>
<?php endforeach;?>
</select>
</fieldset>
</form>

View file

@ -58,7 +58,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
}
public function mkdir($path) {
if ($path == "" || $path == "/" || !$this->is_writeable($path)) {
if ($path == "" || $path == "/" || !$this->is_writable($path)) {
return false;
} else {
$source = $this->getSource($path);
@ -79,7 +79,6 @@ class OC_Filestorage_Shared extends OC_Filestorage {
if ($path == "" || $path == "/") {
$path = $this->datadir.$path;
$sharedItems = OC_Share::getItemsInFolder($path);
global $FAKEDIRS;
$files = array();
foreach ($sharedItems as $item) {
// If item is in the root of the shared storage provider and the item exists add it to the fakedirs
@ -87,7 +86,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
$files[] = basename($item['target']);
}
}
$FAKEDIRS['shared'] = $files;
OC_FakeDirStream::$dirs['shared']=$files;
return opendir('fakedir://shared');
} else {
$source = $this->getSource($path);
@ -281,14 +280,6 @@ class OC_Filestorage_Shared extends OC_Filestorage {
}
}
public function readfile($path) {
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
return $storage->readfile($this->getInternalPath($source));
}
}
public function filectime($path) {
if ($path == "" || $path == "/") {
$ctime = 0;
@ -514,7 +505,13 @@ class OC_Filestorage_Shared extends OC_Filestorage {
return $storage->getLocalFile($this->getInternalPath($source));
}
}
public function touch($path, $mtime=null){
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
return $storage->touch($this->getInternalPath($source),$time);
}
}
}
?>

View file

@ -41,7 +41,8 @@ function handleRemove($name) {
function handleGetThumbnails($albumname) {
OC_Response::enableCaching(3600 * 24); // 24 hour
$thumbnail = OC::$CONFIG_DATADIRECTORY.'/../gallery/'.$albumname.'.png';
error_log(htmlentities($albumname));
$thumbnail = OC::$CONFIG_DATADIRECTORY.'/../gallery/'.urldecode($albumname).'.png';
header('Content-Type: '.OC_Image::getMimeTypeForFile($thumbnail));
OC_Response::sendFile($thumbnail);
}

View file

@ -33,7 +33,7 @@ while ($r = $result->fetchRow()) {
$album_name = $r['album_name'];
$tmp_res = OC_Gallery_Photo::find($r['album_id']);
$a[] = array('name' => $album_name, 'numOfItems' => min($tmp_res->numRows(), 10), 'bgPath' => OC::$WEBROOT.'/data/'.OC_User::getUser().'/gallery/'.$album_name.'.png');
$a[] = array('name' => utf8_encode($album_name), 'numOfItems' => min($tmp_res->numRows(), 10), 'bgPath' => OC::$WEBROOT.'/data/'.OC_User::getUser().'/gallery/'.$album_name.'.png');
}
OC_JSON::success(array('albums'=>$a));

View file

@ -40,8 +40,8 @@ OC_App::addNavigationEntry( array(
'icon' => OC_Helper::imagePath('core', 'places/picture.svg'),
'name' => $l->t('Gallery')));
class OC_GallerySearchProvider extends OC_Search_Provider{
function search($query){
class OC_GallerySearchProvider implements OC_Search_Provider{
static function search($query){
$stmt = OC_DB::prepare('SELECT * FROM *PREFIX*gallery_albums WHERE uid_owner = ? AND album_name LIKE ?');
$result = $stmt->execute(array(OC_User::getUser(),'%'.$query.'%'));
$results=array();
@ -52,7 +52,7 @@ OC_App::addNavigationEntry( array(
}
}
new OC_GallerySearchProvider();
OC_Search::registerProvider('OC_GallerySearchProvider');
require_once('apps/gallery/lib/hooks_handlers.php');
?>

View file

@ -54,9 +54,9 @@ Albums={
event.preventDefault();
galleryRemove(event.data.name);
});
$("a.view", local).attr('href','?view='+escape(a.name));
$('h1',local).text(a.name);
$(".gallery_album_cover", local).attr('title',a.name);
$("a.view", local).attr('href','?view='+decodeURIComponent(escape(a.name)));
$('h1',local).text(decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).attr('title',decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).css('background-repeat', 'no-repeat');
$(".gallery_album_cover", local).css('background-position', '0');
$(".gallery_album_cover", local).css('background-image','url("ajax/galleryOp.php?operation=get_covers&albumname='+escape(a.name)+'")');

View file

@ -5,7 +5,6 @@ OC_Util::addScript('gallery', 'album_cover');
$l = new OC_L10N('gallery');
?>
<div id="notification"><div id="gallery_notification_text">Creating thumbnails</div></div>
<div id="controls">
<div id="scan">
<div id="scanprogressbar"></div>

View file

@ -120,7 +120,10 @@ if($arguments['action']){
OC_Filesystem::readfile($arguments['path']);
exit;
case 'find_music':
OC_JSON::encodedPrint(OC_FileCache::searchByMime('audio'));
$music=OC_FileCache::searchByMime('audio');
$ogg=OC_FileCache::searchByMime('application','ogg');
$music=array_merge($music,$ogg);
OC_JSON::encodedPrint($music);
exit;
}
}

View file

@ -30,4 +30,5 @@ OC_APP::registerPersonal('media','settings');
OC_App::register( array( 'order' => 3, 'id' => 'media', 'name' => 'Media' ));
OC_App::addNavigationEntry(array('id' => 'media_index', 'order' => 2, 'href' => OC_Helper::linkTo('media', 'index.php'), 'icon' => OC_Helper::imagePath('core', 'places/music.svg'), 'name' => $l->t('Music')));
?>
OC_Search::registerProvider('OC_MediaSearchProvider');

View file

@ -56,6 +56,7 @@ class OC_MEDIA{
*/
public static function updateFile($params){
$path=$params['path'];
if(!$path) return;
require_once 'lib_scanner.php';
require_once 'lib_collection.php';
//fix a bug where there were multiply '/' in front of the path, it should only be one
@ -81,8 +82,8 @@ class OC_MEDIA{
}
}
class OC_MediaSearchProvider extends OC_Search_Provider{
function search($query){
class OC_MediaSearchProvider implements OC_Search_Provider{
static function search($query){
require_once('lib_collection.php');
$artists=OC_MEDIA_COLLECTION::getArtists($query);
$albums=OC_MEDIA_COLLECTION::getAlbums(0,$query);
@ -106,5 +107,3 @@ class OC_MediaSearchProvider extends OC_Search_Provider{
}
}
new OC_MediaSearchProvider();
?>

View file

@ -38,6 +38,8 @@ class OC_MEDIA_SCANNER{
*/
public static function scanCollection($eventSource=null){
$music=OC_FileCache::searchByMime('audio');
$ogg=OC_FileCache::searchByMime('application','ogg');
$music=array_merge($music,$ogg);
$eventSource->send('count',count($music));
$songs=0;
foreach($music as $file){

View file

@ -0,0 +1,61 @@
<?php
/**
* HTTP Bearer Authentication handler
*
* Use this class for easy http authentication setup
*
* @package Sabre
* @subpackage HTTP
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_HTTP_BearerAuth extends Sabre_HTTP_AbstractAuth {
/**
* Returns the supplied username and password.
*
* The returned array has two values:
* * 0 - username
* * 1 - password
*
* If nothing was supplied, 'false' will be returned
*
* @return mixed
*/
public function getUserPass() {
// Apache and mod_php
if (($user = $this->httpRequest->getRawServerValue('PHP_AUTH_USER')) && ($pass = $this->httpRequest->getRawServerValue('PHP_AUTH_PW'))) {
return array($user,$pass);
}
// Most other webservers
$auth = $this->httpRequest->getHeader('Authorization');
if (!$auth) return false;
if (strpos(strtolower($auth),'bearer')!==0) return false;
return explode(':', base64_decode(substr($auth, 7)));
}
/**
* Returns an HTTP 401 header, forcing login
*
* This should be called when username and password are incorrect, or not supplied at all
*
* @return void
*/
public function requireLogin() {
$this->httpResponse->setHeader('WWW-Authenticate','Basic realm="' . $this->realm . '"');
$this->httpResponse->sendStatus(401);
}
}

View file

@ -33,6 +33,7 @@ require_once('../../lib/base.php');
OC_Util::checkAppEnabled('remoteStorage');
require_once('Sabre/autoload.php');
require_once('lib_remoteStorage.php');
require_once('BearerAuth.php');
require_once('oauth_ro_auth.php');
ini_set('default_charset', 'UTF-8');
@ -68,7 +69,10 @@ if(count($pathParts) >= 3 && $pathParts[0] == '') {
$server->setBaseUri(OC::$WEBROOT."/apps/remoteStorage/WebDAV.php/$ownCloudUser");
// Auth backend
$authBackend = new OC_Connector_Sabre_Auth_ro_oauth(OC_remoteStorage::getValidTokens($ownCloudUser, $category));
$authBackend = new OC_Connector_Sabre_Auth_ro_oauth(
OC_remoteStorage::getValidTokens($ownCloudUser, $category),
$category
);
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud');//should use $validTokens here
$server->addPlugin($authPlugin);
@ -81,5 +85,6 @@ if(count($pathParts) >= 3 && $pathParts[0] == '') {
// And off we go!
$server->exec();
} else {
die('not the right address format '.var_export($pathParts, true));
//die('not the right address format '.var_export($pathParts, true));
die('not the right address format');
}

View file

@ -0,0 +1,41 @@
<?php
/**
* ownCloud
*
* Original:
* @author Frank Karlitschek
* @copyright 2010 Frank Karlitschek karlitschek@kde.org
*
* Adapted:
* @author Michiel de Jong, 2012
*
* 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/>.
*
*/
// Do not load FS ...
$RUNTIME_NOSETUPFS = true;
require_once('../../../lib/base.php');
OC_Util::checkAppEnabled('remoteStorage');
require_once('Sabre/autoload.php');
require_once('../lib_remoteStorage.php');
ini_set('default_charset', 'UTF-8');
#ini_set('error_reporting', '');
@ob_clean();
echo OC_remoteStorage::deleteToken(file_get_contents("php://input"));

View file

@ -3,3 +3,4 @@ OC_App::register( array(
'order' => 10,
'id' => 'remoteStorage',
'name' => 'remoteStorage compatibility' ));
OC_APP::registerPersonal('remoteStorage','settings');

View file

@ -3,8 +3,8 @@
<id>remoteStorage</id>
<name>remoteStorage compatibility</name>
<description>Enables your users to use ownCloud as their remote storage for unhosted applications.</description>
<version>0.2</version>
<licence>AGPL</licence>
<version>0.5</version>
<licence>AGPL or MIT</licence>
<author>Michiel de Jong</author>
<require>2</require>
</info>

View file

@ -0,0 +1,8 @@
h2 { font-size:2em; font-weight:bold; margin-bottom:1em; white-space:nowrap; }
ul.scopes { list-style:disc; }
ul.scopes li { white-space:nowrap; }
h2 img { width: 50% }
#oauth { margin:4em auto 2em; width:20em; }
#allow-auth { background-color:#5c3; text-shadow:#5e3 0 1px 0; color:#fff;
-webkit-box-shadow:0 1px 1px #fff, 0 1px 1px #5f3 inset; -moz-box-shadow:0 1px 1px #fff, 0 1px 1px #5f3 inset; box-shadow:0 1px 1px #fff, 0 1px 1px #5f3 inset; }
#deny-auth { padding:0; margin:.7em; border:0; background:none; font-size:1.2em; -moz-box-shadow: 0 0 0 #fff, 0 0 0 #fff inset; -webkit-box-shadow: 0 0 0 #fff, 0 0 0 #fff inset; box-shadow: 0 0 0 #fff, 0 0 0 #fff inset; }

View file

@ -8,7 +8,7 @@
* @copyright 2010 Frank Karlitschek karlitschek@kde.org
*
* Adapted:
* @author Michiel de Jong, 2011
* @author Michiel de Jong, 2012
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -17,11 +17,11 @@
*
* 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
* 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/>.
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
@ -39,24 +39,8 @@ ini_set('default_charset', 'UTF-8');
#ini_set('error_reporting', '');
@ob_clean();
//allow use as remote storage for other websites
if(isset($_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Max-Age: 3600');
header('Access-Control-Allow-Methods: OPTIONS, GET, PUT, DELETE, PROPFIND');
header('Access-Control-Allow-Headers: Authorization, Content-Type');
} else {
header('Access-Control-Allow-Origin: *');
}
$path = substr($_SERVER["REQUEST_URI"], strlen($_SERVER["SCRIPT_NAME"]));
$pathParts = explode('/', $path);
// for webdav:
// 0/ 1 / 2 / 3 / 4 / 5 / 6 / 7
// /$ownCloudUser/remoteStorage/webdav/$userHost/$userName/$dataScope/$key
// for oauth:
// 0/ 1 / 2 / 3 / 4
// /$ownCloudUser/remoteStorage/oauth/auth
$pathParts = explode('/', $path);
if(count($pathParts) == 2 && $pathParts[0] == '') {
//TODO: input checking. these explodes may fail to produces the desired arrays:
@ -66,19 +50,69 @@ if(count($pathParts) == 2 && $pathParts[0] == '') {
if($k=='user_address'){
$userAddress=$v;
} else if($k=='redirect_uri'){
$appUrl=$v;
$appUrlParts=explode('/', $v);
$appUrl = $appUrlParts[2];//bit dodgy i guess
} else if($k=='scope'){
$category=$v;
$categories=$v;
}
}
$currUser = OC_User::getUser();
if($currUser == $ownCloudUser) {
if(isset($_POST['allow'])) {
//TODO: check if this can be faked by editing the cookie in firebug!
$token=OC_remoteStorage::createCategory($appUrl, $category);
$token=OC_remoteStorage::createCategories($appUrl, $categories);
header('Location: '.$_GET['redirect_uri'].'#access_token='.$token.'&token_type=bearer');
} else {
echo '<form method="POST"><input name="allow" type="submit" value="Allow this web app to store stuff on your owncloud."></form>';
?>
<!DOCTYPE html>
<html>
<head>
<title>ownCloud</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="../../../core/img/favicon.png" /><link rel="apple-touch-icon-precomposed" href="../../../core/img/favicon-touch.png" />
<link rel="stylesheet" href="../../../core/css/styles.css" type="text/css" media="screen" />
<link rel="stylesheet" href="../auth.css" type="text/css" media="screen" />
</head>
<body id="body-login">
<div id="login">
<header>
<div id="header">
<img src="../../../core/img/owncloud-logo-medium-white.png" alt="ownCloud" />
</div>
</header>
<section id="main">
<div id="oauth">
<h2><img src="../remoteStorage-big.png" alt="remoteStorage" /></h2>
<p><strong><?php $appUrlParts = explode('/', $_GET['redirect_uri']); echo htmlentities($appUrlParts[2]); ?></strong>
requests read &amp; write access to your
<?php
$categories = explode(',', htmlentities($_GET['scope']));
if(!count($categories)) {
echo htmlentities($_GET['scope']);
} else {
echo '<em>'.$categories[0].'</em>';
if(count($categories)==2) {
echo ' and <em>'.$categories[1].'</em>';
} else if(count($categories)>2) {
for($i=1; $i<count($categories)-1; $i++) {
echo ', <em>'.$categories[$i].'</em>';
}
echo ', and <em>'.$categories[$i].'</em>';
}
}
?>.
</p>
<form accept-charset="UTF-8" method="post">
<input id="allow-auth" name="allow" type="submit" value="Allow" />
<input id="deny-auth" name="deny" type="submit" value="Deny" />
</form>
</div>
</section>
</div>
<footer><p class="info"><a href="http://owncloud.org/">ownCloud</a> &ndash; web services under your control</p></footer>
</body>
</html>
<?php
}
} else {
if((isset($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'])) {
@ -88,13 +122,13 @@ if(count($pathParts) == 2 && $pathParts[0] == '') {
}
$url .= $_SERVER['SERVER_NAME'];
$url .= substr($_SERVER['SCRIPT_NAME'], 0, -strlen('apps/remoteStorage/compat.php'));
die('You are '.($currUser?'logged in as '.$currUser.' instead of '.$ownCloudUser:'not logged in').'. Please '
.'<input type="submit" onclick="'
."window.open('$url','Close me!','height=600,width=300');"
.'" value="log in">'
.', close the pop-up, and '
.'<form method="POST"><input name="allow" type="submit" value="Click here"></form>');
if($currUser) {
die('You are logged in as '.$currUser.' instead of '.$ownCloudUser);
} else {
header('Location: /?redirect_url='.urlencode('/apps/remoteStorage/auth.php'.$_SERVER['PATH_INFO'].'?'.$_SERVER['QUERY_STRING']));
}
}
} else {
die('please use auth.php/username?params. '.var_export($pathParts, true));
//die('please use auth.php/username?params. '.var_export($pathParts, true));
die('please use auth.php/username?params.');
}

View file

@ -2,11 +2,13 @@
class OC_remoteStorage {
public static function getValidTokens($ownCloudUser, $category) {
$query=OC_DB::prepare("SELECT token,appUrl FROM *PREFIX*authtoken WHERE user=? AND category=? LIMIT 100");
$result=$query->execute(array($ownCloudUser,$category));
$query=OC_DB::prepare("SELECT token,appUrl,category FROM *PREFIX*authtoken WHERE user=? LIMIT 100");
$result=$query->execute(array($ownCloudUser));
$ret = array();
while($row=$result->fetchRow()){
$ret[$row['token']]=true;
if(in_array($category, explode(',', $row['category']))) {
$ret[$row['token']]=true;
}
}
return $ret;
}
@ -18,8 +20,8 @@ class OC_remoteStorage {
$ret = array();
while($row=$result->fetchRow()){
$ret[$row['token']] = array(
'appUrl' => $row['appurl'],
'category' => $row['category'],
'appUrl' => $row['appUrl'],
'categories' => $row['category'],
);
}
return $ret;
@ -29,22 +31,25 @@ class OC_remoteStorage {
$user=OC_User::getUser();
$query=OC_DB::prepare("DELETE FROM *PREFIX*authtoken WHERE token=? AND user=?");
$result=$query->execute(array($token,$user));
return 'unknown';//how can we see if any rows were affected?
}
private static function addToken($token, $appUrl, $category){
private static function addToken($token, $appUrl, $categories){
$user=OC_User::getUser();
$query=OC_DB::prepare("INSERT INTO *PREFIX*authtoken (`token`,`appUrl`,`user`,`category`) VALUES(?,?,?,?)");
$result=$query->execute(array($token,$appUrl,$user,$category));
$result=$query->execute(array($token,$appUrl,$user,$categories));
}
public static function createCategory($appUrl, $category) {
public static function createCategories($appUrl, $categories) {
$token=uniqid();
self::addToken($token, $appUrl, $category);
//TODO: input checking on $category
OC_Util::setupFS(OC_User::getUser());
$scopePathParts = array('remoteStorage', $category);
for($i=0;$i<=count($scopePathParts);$i++){
$thisPath = '/'.implode('/', array_slice($scopePathParts, 0, $i));
if(!OC_Filesystem::file_exists($thisPath)) {
OC_Filesystem::mkdir($thisPath);
self::addToken($token, $appUrl, $categories);
foreach(explode(',', $categories) as $category) {
//TODO: input checking on $category
$scopePathParts = array('remoteStorage', $category);
for($i=0;$i<=count($scopePathParts);$i++){
$thisPath = '/'.implode('/', array_slice($scopePathParts, 0, $i));
if(!OC_Filesystem::file_exists($thisPath)) {
OC_Filesystem::mkdir($thisPath);
}
}
}
return base64_encode('remoteStorage:'.$token);

View file

@ -16,9 +16,10 @@
class OC_Connector_Sabre_Auth_ro_oauth extends Sabre_DAV_Auth_Backend_AbstractBasic {
private $validTokens;
public function __construct($validTokensArg) {
private $category;
public function __construct($validTokensArg, $categoryArg) {
$this->validTokens = $validTokensArg;
$this->category = $categoryArg;
}
/**
@ -31,29 +32,31 @@ class OC_Connector_Sabre_Auth_ro_oauth extends Sabre_DAV_Auth_Backend_AbstractBa
*/
protected function validateUserPass($username, $password){
//always give read-only:
if(in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD', 'OPTIONS'))) {
OC_Util::setUpFS();
return true;
} else if(isset($this->validTokens[$password]) && $this->validTokens[$password] == $username) {
if(($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
|| (isset($this->validTokens[$password]))
|| (($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
) {
OC_Util::setUpFS();
return true;
} else {
var_export($_SERVER);
var_export($this->validTokens);
die('not getting in with "'.$username.'"/"'.$password.'"!');
//var_export($_SERVER);
//var_export($this->validTokens);
//die('not getting in with "'.$username.'"/"'.$password.'"!');
return false;
}
}
//overwriting this to make it not automatically fail if no auth header is found:
public function authenticate(Sabre_DAV_Server $server,$realm) {
$auth = new Sabre_HTTP_BasicAuth();
$auth = new Sabre_HTTP_BearerAuth();
$auth->setHTTPRequest($server->httpRequest);
$auth->setHTTPResponse($server->httpResponse);
$auth->setRealm($realm);
$userpass = $auth->getUserPass();
if (!$userpass) {
if(in_array($_SERVER['REQUEST_METHOD'], array('OPTIONS'))) {
if(($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
||(($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
) {
$userpass = array('', '');
} else {
$auth->requireLogin();

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,7 @@
<?php
require_once('lib_remoteStorage.php');
$tmpl = new OC_Template( 'remoteStorage', 'settings');
return $tmpl->fetchPage();
?>

View file

@ -0,0 +1,28 @@
<fieldset class="personalblock">
<?php
echo '<img src="/apps/remoteStorage/remoteStorage.png" style="width:16px"> '
.'<strong>'.$l->t('remoteStorage').'</strong> user address: '
.OC_User::getUser().'@'.$_SERVER['SERVER_NAME']
.' (<a href="http://unhosted.org/">more info</a>)';
?>
<p><em>Apps that currently have access to your ownCloud:</em></p>
<script>
function revokeToken(token) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/apps/remoteStorage/ajax/revokeToken.php', true);
xhr.send(token);
}
</script>
<ul>
<?php
foreach(OC_remoteStorage::getAllTokens() as $token => $details) {
echo '<li onmouseover="'
.'document.getElementById(\'revoke_'.$token.'\').style.display=\'inline\';"'
.'onmouseout="document.getElementById(\'revoke_'.$token.'\').style.display=\'none\';"'
.'> <strong>'.$details['appUrl'].'</strong>: '.$details['categories']
.' <a href="#" title="Revoke" class="action" style="display:none" id="revoke_'.$token.'" onclick="'
.'revokeToken(\''.$token.'\');this.parentNode.style.display=\'none\';"'
.'><img src="/core/img/actions/delete.svg"></a></li>'."\n";
}
?></ul>
</fieldset>

View file

@ -20,7 +20,7 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase');
$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
if ($_POST) {
foreach($params as $param){
@ -29,12 +29,12 @@ if ($_POST) {
}
elseif('ldap_tls' == $param) {
// unchecked checkboxes are not included in the post paramters
OC_Appconfig::setValue('user_ldap', $param, 0);
OC_Appconfig::setValue('user_ldap', $param, 0);
}
elseif('ldap_nocase' == $param) {
OC_Appconfig::setValue('user_ldap', $param, 0);
}
}
}

View file

@ -6,15 +6,16 @@
<p><label for="ldap_dn"><?php echo $l->t('Name');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" />
<label for="ldap_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_password" name="ldap_password" value="<?php echo $_['ldap_password']; ?>" />
<small><?php echo $l->t('Leave both empty for anonymous bind for search, then bind with users credentials.');?></small></p>
<p><label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" />
<label for="ldap_filter"><?php echo $l->t('Filter (use %%uid placeholder)');?></label><input type="text" id="ldap_filter" name="ldap_filter" value="<?php echo $_['ldap_filter']; ?>" /></p>
<p><label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
<p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" /><small><?php echo $l->t('use %%uid placeholder, e.g. uid=%%uid');?></small></p>
<p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?> </p>
<p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
<small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
<p><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?>><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label></p>
<p><input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if ($_['ldap_nocase']) echo ' checked'; ?>><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label></p>
<p><label for="ldap_quota">Quota Attribute</label><input type="text" id="ldap_quota" name="ldap_quota" value="<?php echo $_['ldap_quota']; ?>" />
<p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" />
<label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
<p><label for="ldap_email">Email Attribute</label><input type="text" id="ldap_email" name="ldap_email" value="<?php echo $_['ldap_email']; ?>" /></p>
<p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
<input type="submit" value="Save" />
</fieldset>
</form>

View file

@ -32,7 +32,8 @@ class OC_USER_LDAP extends OC_User_Backend {
protected $ldap_dn;
protected $ldap_password;
protected $ldap_base;
protected $ldap_filter;
protected $ldap_login_filter;
protected $ldap_userlist_filter;
protected $ldap_tls;
protected $ldap_nocase;
protected $ldap_display_name;
@ -49,7 +50,8 @@ class OC_USER_LDAP extends OC_User_Backend {
$this->ldap_dn = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
$this->ldap_password = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
$this->ldap_base = OC_Appconfig::getValue('user_ldap', 'ldap_base','');
$this->ldap_filter = OC_Appconfig::getValue('user_ldap', 'ldap_filter','');
$this->ldap_login_filter = OC_Appconfig::getValue('user_ldap', 'ldap_login_filter','');
$this->ldap_userlist_filter = OC_Appconfig::getValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
$this->ldap_tls = OC_Appconfig::getValue('user_ldap', 'ldap_tls', 0);
$this->ldap_nocase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
$this->ldap_display_name = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
@ -61,7 +63,7 @@ class OC_USER_LDAP extends OC_User_Backend {
&& !empty($this->ldap_port)
&& ((!empty($this->ldap_dn) && !empty($this->ldap_password)) || (empty($this->ldap_dn) && empty($this->ldap_password)))
&& !empty($this->ldap_base)
&& !empty($this->ldap_filter)
&& !empty($this->ldap_login_filter)
&& !empty($this->ldap_display_name)
)
{
@ -79,9 +81,13 @@ class OC_USER_LDAP extends OC_User_Backend {
if( !$this->ldap_dc )
return false;
$quota = $this->ldap_dc[$this->ldap_quota_attr][0];
if(!empty($this->ldap_quota_attr)) {
$quota = $this->ldap_dc[strtolower($this->ldap_quota_attr)][0];
} else {
$quota = false;
}
$quota = $quota != -1 ? $quota : $this->ldap_quota_def;
OC_Preferences::setValue($uid, 'files', 'quota', $quota);
OC_Preferences::setValue($uid, 'files', 'quota', OC_Helper::computerFileSize($quota));
}
private function setEmail( $uid ) {
@ -127,7 +133,7 @@ class OC_USER_LDAP extends OC_User_Backend {
return false;
// get dn
$filter = str_replace('%uid', $uid, $this->ldap_filter);
$filter = str_replace('%uid', $uid, $this->ldap_login_filter);
$sr = ldap_search( $this->getDs(), $this->ldap_base, $filter );
$entries = ldap_get_entries( $this->getDs(), $sr );
@ -152,7 +158,7 @@ class OC_USER_LDAP extends OC_User_Backend {
return false;
}
if(!empty($this->ldap_quota) && !empty($this->ldap_quota_def)) {
if(!empty($this->ldap_quota_attr) || !empty($this->ldap_quota_def)) {
$this->setQuota($uid);
}
@ -161,7 +167,7 @@ class OC_USER_LDAP extends OC_User_Backend {
}
if($this->ldap_nocase) {
$filter = str_replace('%uid', $uid, $this->ldap_filter);
$filter = str_replace('%uid', $uid, $this->ldap_login_filter);
$sr = ldap_search( $this->getDs(), $this->ldap_base, $filter );
$entries = ldap_get_entries( $this->getDs(), $sr );
if( $entries['count'] == 1 ) {
@ -187,7 +193,7 @@ class OC_USER_LDAP extends OC_User_Backend {
if(!$this->configured){
return false;
}
$dn = $this->getDn($uid);
$dn = $this->getDc($uid);
return !empty($dn);
}
@ -202,8 +208,7 @@ class OC_USER_LDAP extends OC_User_Backend {
return false;
// get users
$filter = 'objectClass=person';
$sr = ldap_search( $this->getDs(), $this->ldap_base, $filter );
$sr = ldap_search( $this->getDs(), $this->ldap_base, $this->ldap_userlist_filter );
$entries = ldap_get_entries( $this->getDs(), $sr );
if( $entries['count'] == 0 )
return false;

View file

@ -3,8 +3,8 @@
<id>user_webfinger</id>
<name>Webfinger</name>
<description>Provide WebFinger for all users so they get a user address like user@owncloudinstance which can be used for unhosted applications. If you don't run ownCloud in the root of your domain, for instance if you run it on example.com/owncloud/, then make sure you link example.com/.well-known/ to example.com/owncloud/apps/user_webfinger/ - by running something like "ln -s /var/www/owncloud/apps/user_webfinger /var/www/.well-known". Only enable this app if you run this ownCloud installation on a public web address, not if you run it on an intranet or on localhost.</description>
<version>0.1</version>
<licence>AGPL</licence>
<version>0.2</version>
<licence>AGPL or MIT</licence>
<author>Michiel de Jong</author>
<require>2</require>
</info>

View file

@ -4,13 +4,13 @@ if($_SERVER['SCRIPT_NAME'] == '/.well-known/host-meta.php') {
} else {
header('Please-first: activate');
}
header("Content-Type: application/xml+xrd");
header("Content-Type: application/xrd+xml");
echo "<";
?>
?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0" xmlns:hm="http://host-meta.net/xrd/1.0">
<hm:Host xmlns="http://host-meta.net/xrd/1.0"><?php echo $_SERVER['SERVER_NAME'] ?></hm:Host>
<Link rel="lrdd" template="http<?php echo ($_SERVER['HTTPS']?'s':''); ?>://<?php echo $_SERVER['SERVER_NAME'] ?>/.well-known/webfinger.php?q={uri}">
<Link rel="lrdd" template="http<?php echo (isset($_SERVER['HTTPS'])?'s':''); ?>://<?php echo $_SERVER['SERVER_NAME'] ?>/.well-known/webfinger.php?q={uri}">
</Link>
</XRD>

View file

@ -4,7 +4,7 @@ if($_SERVER['SCRIPT_NAME'] == '/.well-known/webfinger.php') {
} else {
header('Please-first: activate');
}
// header("Content-Type: application/xml+xrd");
header("Content-Type: application/xrd+xml");
// calculate the documentroot
// modified version of the one in lib/base.php that takes the .well-known symlink into account
@ -22,7 +22,7 @@ if($_GET['q']) {
if(substr($userName, 0, 5) == 'acct:') {
$userName = substr($userName, 5);
}
if($_SERVER['HTTPS']) {
if(isset($_SERVER['HTTPS'])) {
$baseAddress = 'https://'.$_SERVER['SERVER_NAME'].'/apps/remoteStorage/';
} else {
$baseAddress = 'http://'.$_SERVER['SERVER_NAME'].'/apps/remoteStorage/';

35
core/ajax/appconfig.php Normal file
View file

@ -0,0 +1,35 @@
<?php
/**
* Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
require_once ("../../lib/base.php");
OC_JSON::checkLoggedIn();
$action=isset($_POST['action'])?$_POST['action']:$_GET['action'];
$result=false;
switch($action){
case 'getValue':
$result=OC_Appconfig::getValue($_GET['app'],$_GET['key'],$_GET['default']);
break;
case 'setValue':
$result=OC_Appconfig::setValue($_POST['app'],$_POST['key'],$_POST['value']);
break;
case 'getApps':
$result=OC_Appconfig::getApps();
break;
case 'getKeys':
$result=OC_Appconfig::getKeys($_GET['app']);
break;
case 'hasKey':
$result=OC_Appconfig::hasKey($_GET['app'],$_GET['key']);
break;
case 'deleteKey':
$result=OC_Appconfig::deleteKey($_POST['app'],$_POST['key']);
break;
case 'deleteApp':
$result=OC_Appconfig::deleteApp($_POST['app']);
break;
}
OC_JSON::success(array('data'=>$result));

View file

@ -128,4 +128,6 @@ div.jp-play-bar, div.jp-seek-bar { padding:0; }
li.error { width:640px; margin:4em auto; padding:1em 1em 1em 4em; background:#ffe .8em .8em no-repeat; color: #FF3B3B; border:1px solid #ccc; -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; }
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { overflow: hidden; text-overflow: ellipsis; }
.hint { background-image: url('/core/img/actions/info.png'); background-repeat:no-repeat; color: #777777; padding-left: 25px; background-position: 0 0.3em;}
.separator { display: inline; border-left: 1px solid #d3d3d3; border-right: 1px solid #fff; height: 10px; width:0px; margin: 4px; }
.separator { display: inline; border-left: 1px solid #d3d3d3; border-right: 1px solid #fff; height: 10px; width:0px; margin: 4px; }
a.bookmarklet { background-color: #ddd; border:1px solid #ccc; padding: 5px;padding-top: 0px;padding-bottom: 2px; text-decoration: none; margin-top: 5px }

55
core/js/config.js Normal file
View file

@ -0,0 +1,55 @@
/**
* Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
OC.AppConfig={
url:OC.filePath('core','ajax','appconfig.php'),
getCall:function(action,data,callback){
data.action=action;
$.getJSON(OC.AppConfig.url,data,function(result){
if(result.status='success'){
if(callback){
callback(result.data);
}
}
});
},
postCall:function(action,data,callback){
data.action=action;
$.post(OC.AppConfig.url,data,function(result){
if(result.status='success'){
if(callback){
callback(result.data);
}
}
},'json');
},
getValue:function(app,key,defaultValue,callback){
if(typeof defaultValue=='function'){
callback=defaultValue;
defaultValue=null;
}
OC.AppConfig.getCall('getValue',{app:app,key:key,default:defaultValue},callback);
},
setValue:function(app,key,value){
OC.AppConfig.postCall('setValue',{app:app,key:key,value:value});
},
getApps:function(callback){
OC.AppConfig.getCall('getApps',{},callback);
},
getKeys:function(app,callback){
OC.AppConfig.getCall('getKeys',{app:app},callback);
},
hasKey:function(app,key,callback){
OC.AppConfig.getCall('hasKey',{app:app,key:key},callback);
},
deleteKey:function(app,key){
OC.AppConfig.postCall('deleteKey',{app:app,key:key});
},
deleteApp:function(app){
OC.AppConfig.postCall('deleteApp',{app:app});
},
}
//TODO OC.Preferences

View file

@ -125,7 +125,8 @@ OC={
OC.search.showResults(results);
});
}
}
},
dialogs:OCdialogs
};
OC.search.customResults={};
OC.search.currentResult=-1;
@ -252,16 +253,22 @@ function replaceSVG(){
$('.svg').each(function(index,element){
element=$(element);
var background=element.css('background-image');
if(background && background!='none'){
background=background.substr(0,background.length-4)+'png)';
element.css('background-image',background);
if(background){
var i=background.lastIndexOf('.svg');
if(i>=0){
background=background.substr(0,i)+'.png'+background.substr(i+4);
element.css('background-image',background);
}
}
element.find('*').each(function(index,element) {
element=$(element);
var background=element.css('background-image');
if(background && background!='none'){
background=background.substr(0,background.length-4)+'png)';
element.css('background-image',background);
if(background){
var i=background.lastIndexOf('.svg');
if(i>=0){
background=background.substr(0,i)+'.png'+background.substr(i+4);
element.css('background-image',background);
}
}
});
});
@ -444,4 +451,33 @@ $.fn.filterAttr = function(attr_name, attr_value) {
return this.filter(function() { return $(this).attr(attr_name) === attr_value; });
};
function humanFileSize(size) {
humanList = ['B', 'kB', 'MB', 'GB', 'TB'];
// Calculate Log with base 1024: size = 1024 ** order
order = Math.floor(Math.log(size) / Math.log(1024));
// Stay in range of the byte sizes that are defined
order = Math.min(humanList.length - 1, order);
readableFormat = humanList[order];
relativeSize = (size / Math.pow(1024, order)).toFixed(1);
if(relativeSize.substr(relativeSize.length-2,2)=='.0'){
relativeSize=relativeSize.substr(0,relativeSize.length-2);
}
return relativeSize + ' ' + readableFormat;
}
function simpleFileSize(bytes) {
mbytes = Math.round(bytes/(1024*1024/10))/10;
if(bytes == 0) { return '0'; }
else if(mbytes < 0.1) { return '< 0.1'; }
else if(mbytes > 1000) { return '> 1000'; }
else { return mbytes.toFixed(1); }
}
function formatDate(date){
if(typeof date=='number'){
date=new Date(date);
}
var monthNames = [ t('files','January'), t('files','February'), t('files','March'), t('files','April'), t('files','May'), t('files','June'),
t('files','July'), t('files','August'), t('files','September'), t('files','October'), t('files','November'), t('files','December') ];
return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+date.getMinutes();
}

View file

@ -12,6 +12,11 @@
'minWidth': 'default;',
};
$.extend(settings,options);
$.each(this.children(),function(i,option){
if($(option).attr('selected') && settings.checked.indexOf($(option).val())==-1){
settings.checked.push($(option).val());
}
});
var button=$('<div class="multiselect button"><span>'+settings.title+'</span><span>▾</span></div>');
var span=$('<span/>');
span.append(button);
@ -46,9 +51,11 @@
});
button.addClass('active');
event.stopPropagation();
var options=$(this).parent().next().children().map(function(){return $(this).val();});
var options=$(this).parent().next().children();
var list=$('<ul class="multiselectoptions"/>').hide().appendTo($(this).parent());
function createItem(item,checked){
function createItem(element,checked){
element=$(element);
var item=element.val();
var id='ms'+multiSelectId+'-option-'+item;
var input=$('<input id="'+id+'" type="checkbox"/>');
var label=$('<label for="'+id+'">'+item+'</label>');
@ -61,6 +68,7 @@
input.change(function(){
var groupname=$(this).next().text();
if($(this).is(':checked')){
element.attr('selected','selected');
if(settings.oncheck){
if(settings.oncheck(groupname)===false){
$(this).attr('checked', false);
@ -70,6 +78,7 @@
settings.checked.push(groupname);
}else{
var index=settings.checked.indexOf(groupname);
element.attr('selected',null);
if(settings.onuncheck){
if(settings.onuncheck(groupname)===false){
$(this).attr('checked',true);
@ -119,11 +128,11 @@
var li=$(this).parent();
$(this).remove();
li.text('+ '+settings.createText);
li.before(createItem($(this).val()));
li.before(createItem(this));
var select=button.parent().next();
select.append($('<option selected="selected" value="'+$(this).val()+'">'+$(this).val()+'</option>'));
li.prev().children('input').trigger('click');
button.parent().data('preventHide',false);
var select=button.parent().next();
select.append($('<option value="'+$(this).val()+'">'+$(this).val()+'</option>'));
if(settings.createCallback){
settings.createCallback();
}

145
core/js/oc-dialogs.js Normal file
View file

@ -0,0 +1,145 @@
/**
* ownCloud
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.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/>.
*
* todo(bartek): add select option in form
*/
/**
* this class ease usage of jquery dialogs
*/
OCdialogs = {
/**
* displays alert dialog
* @param text content of dialog
* @param title dialog title
* @param callback which will be triggered when user press OK
*/
alert:function(text, title, callback) {
var content = '<p><span class="ui-icon ui-icon-alert"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback);
},
/**
* displays info dialog
* @param text content of dialog
* @param title dialog title
* @param callback which will be triggered when user press OK
*/
info:function(text, title, callback) {
var content = '<p><span class="ui-icon ui-icon-info"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback);
},
/**
* displays confirmation dialog
* @param text content of dialog
* @param title dialog title
* @param callback which will be triggered when user press YES or NO (true or false would be passed to callback respectively)
*/
confirm:function(text, title, callback) {
var content = '<p><span class="ui-icon ui-icon-notice"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.YES_NO_BUTTON, callback);
},
/**
* prompt for user input
* @param text content of dialog
* @param title dialog title
* @param callback which will be triggered when user press OK (input text will be passed to callback)
*/
prompt:function(text, title, callback) {
var content = '<p><span class="ui-icon ui-icon-pencil"></span>'+text+':<br/><input type="text" id="oc-dialog-prompt-input" style="width:90%"></p>';
OCdialogs.message(content, title, OCdialogs.PROMPT_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback);
},
/**
* prompt user for input with custom form
* fields should be passed in following format: [{text:'prompt text', name:'return name', type:'input type'},...]
* @param fields to display
* @param title dialog title
* @param callback which will be triggered when user press OK (user answers will be passed to callback in following format: [{name:'return name', value: 'user value'},...])
*/
form:function(fields, title, callback) {
var content = '<table>';
for (var a in fields) {
content += '<tr><td>'+fields[a].text+'</td><td>';
var type=fields[a].type;
if (type == 'text' || type == 'checkbox' || type == 'password')
content += '<input type="'+type+'" name="'+fields[a].name+'">';
content += "</td></tr>"
}
content += "</table>";
OCdialogs.message(content, title, OCdialogs.FORM_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback);
},
message:function(content, title, dialog_type, buttons, callback) {
var c_name = 'oc-dialog-'+OCdialogs.dialogs_counter+'-content';
var c_id = '#'+c_name;
var d = '<div id="'+c_name+'" title="'+title+'">'+content+'</div>';
$('body').append(d);
var b = [];
switch (buttons) {
case OCdialogs.YES_NO_BUTTONS:
b[1] = {text: t('dialogs', 'No'), click: function(){ if (callback != undefined) callback(false); $(c_id).dialog('close'); }};
b[0] = {text: t('dialogs', 'Yes'), click: function(){ if (callback != undefined) callback(true); $(c_id).dialog('close');}};
break;
case OCdialogs.OK_CANCEL_BUTTONS:
b[1] = {text: t('dialogs', 'Cancel'), click: function(){$(c_id).dialog('close'); }};
case OCdialogs.OK_BUTTON: // fallthrough
var f;
switch(dialog_type) {
case OCdialogs.ALERT_DIALOG:
f = function(){$(c_id).dialog('close'); };
break;
case OCdialogs.PROMPT_DIALOG:
f = function(){OCdialogs.prompt_ok_handler(callback, c_id)};
break;
case OCdialogs.FORM_DIALOG:
f = function(){OCdialogs.form_ok_handler(callback, c_id)};
break;
}
b[0] = {text: t('dialogs', 'Ok'), click: f};
break;
}
$(c_id).dialog({width: 4*$(document).width()/9, height: $(d).height() + 150, modal: false, buttons: b});
OCdialogs.dialogs_counter++;
},
// dialogs buttons types
YES_NO_BUTTONS: 70,
OK_BUTTONS: 71,
OK_CANCEL_BUTTONS: 72,
// dialogs types
ALERT_DIALOG: 80,
INFO_DIALOG: 81,
PROMPT_DIALOG: 82,
FORM_DIALOG: 83,
dialogs_counter: 0,
determineValue: function(element) {
switch ($(element).attr('type')) {
case 'checkbox': return $(element).attr('checked') != undefined;
}
return $(element).val();
},
prompt_ok_handler: function(callback, c_id){callback(true, $(c_id + " input#oc-dialog-prompt-input").val()); $(c_id).dialog('close');},
form_ok_handler: function(callback, c_id) {
var r = [];
var c = 0;
$(c_id + ' input').each(function(i, elem) {
r[c] = {name: $(elem).attr('name'), value: OCdialogs.determineValue(elem)};
c++;
});
$(c_id).dialog('close');
callback(r);
}
};

77
dav.php Normal file
View file

@ -0,0 +1,77 @@
<?php
/**
* ownCloud
*
* @author Jakob Sack
* @copyright 2012 Jakob Sack owncloud@jakobsack.de
*
* 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/>.
*
*/
require_once('lib/base.php');
// Backends we always need (auth, principal and files)
$backends = array(
'auth' => new OC_Connector_Sabre_Auth(),
'principal' => new OC_Connector_Sabre_Principal()
);
// Root nodes
$nodes = array(
new Sabre_CalDAV_Principal_Collection($backends['principal'])
);
// Plugins
$plugins = array(
new Sabre_DAV_Auth_Plugin($backends['auth'],'ownCloud'),
new Sabre_DAVACL_Plugin(),
new Sabre_DAV_Browser_Plugin(false) // Show something in the Browser, but no upload
);
// Load the plugins etc we need for usual file sharing
$backends['lock'] = new OC_Connector_Sabre_Locks();
$plugins[] = new Sabre_DAV_Locks_Plugin($backends['lock']);
// Add a RESTful user directory
// /files/$username/
if( OC_User::isLoggedIn()){
$currentuser = OC_User::getUser();
$files = new Sabre_DAV_SimpleCollection('files');
foreach( OC_User::getUsers() as $username ){
if( $username == $currentuser ){
$public = new OC_Connector_Sabre_Directory('.');
$files->addChild( new Sabre_DAV_SimpleCollection( $username, $public->getChildren()));
}
else{
$files->addChild(new Sabre_DAV_SimpleCollection( $username ));
}
}
$nodes[] = $files;
}
// Get the other plugins and nodes
OC_Hook::emit( 'OC_DAV', 'initialize', array( 'backends' => &$backends, 'nodes' => &$nodes, 'plugins' => &$plugins ));
// Fire up server
$server = new Sabre_DAV_Server($nodes);
$server->setBaseUri(OC::$WEBROOT.'/dav.php');
// Load additional plugins
foreach( $plugins as &$plugin ){
$server->addPlugin( $plugin );
} unset( $plugin ); // Always do this after foreach with references!
// And off we go!
$server->exec();

View file

@ -70,7 +70,7 @@
<default>
</default>
<notnull>true</notnull>
<length>4</length>
<length>8</length>
</field>
<field>
@ -96,7 +96,7 @@
<type>integer</type>
<default></default>
<notnull>true</notnull>
<length>4</length>
<length>8</length>
</field>
<field>
@ -105,7 +105,7 @@
<default>
</default>
<notnull>true</notnull>
<length>4</length>
<length>8</length>
</field>
<field>
@ -114,7 +114,7 @@
<default>
</default>
<notnull>true</notnull>
<length>4</length>
<length>8</length>
</field>
<field>
@ -291,7 +291,7 @@
<type>integer</type>
<default></default>
<notnull>false</notnull>
<length>4</length>
<length>8</length>
</field>
<field>
@ -427,102 +427,6 @@
</table>
<table>
<name>*dbprefix*principalgroups</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>principal_id</name>
<type>integer</type>
<default></default>
<notnull>true</notnull>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>member_id</name>
<type>integer</type>
<default></default>
<notnull>true</notnull>
<unsigned>true</unsigned>
<length>4</length>
</field>
<index>
<name>principals_members_index</name>
<unique>true</unique>
<field>
<name>principal_id</name>
<sorting>ascending</sorting>
</field>
<field>
<name>member_id</name>
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*principals</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>uri</name>
<type>text</type>
<default></default>
<notnull>false</notnull>
<length>255</length>
</field>
<field>
<name>displayname</name>
<type>text</type>
<default></default>
<notnull>false</notnull>
<length>255</length>
</field>
<index>
<name>uri</name>
<unique>true</unique>
<field>
<name>uri</name>
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*properties</name>

View file

@ -16,12 +16,13 @@ foreach ($_FILES['files']['error'] as $error) {
if ($error != 0) {
$l=new OC_L10N('files');
$errors = array(
0=>$l->t("There is no error, the file uploaded with success"),
1=>$l->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
2=>$l->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
3=>$l->t("The uploaded file was only partially uploaded"),
4=>$l->t("No file was uploaded"),
6=>$l->t("Missing a temporary folder")
UPLOAD_ERR_OK=>$l->t("There is no error, the file uploaded with success"),
UPLOAD_ERR_INI_SIZE=>$l->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
UPLOAD_ERR_FORM_SIZE=>$l->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
UPLOAD_ERR_PARTIAL=>$l->t("The uploaded file was only partially uploaded"),
UPLOAD_ERR_NO_FILE=>$l->t("No file was uploaded"),
UPLOAD_ERR_NO_TMP_DIR=>$l->t("Missing a temporary folder"),
UPLOAD_ERR_CANT_WRITE=>$l->t('Failed to write to disk'),
);
OC_JSON::error(array("data" => array( "message" => $errors[$error] )));
exit();
@ -48,7 +49,8 @@ if(strpos($dir,'..') === false){
for($i=0;$i<$fileCount;$i++){
$target=stripslashes($dir) . $files['name'][$i];
if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i],$target)){
$result[]=array( "status" => "success", 'mime'=>OC_Filesystem::getMimeType($target),'size'=>OC_Filesystem::filesize($target),'name'=>$files['name'][$i]);
$meta=OC_FileCache::getCached($target);
$result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'],'name'=>$files['name'][$i]);
}
}
OC_JSON::encodedPrint($result);

View file

@ -7,4 +7,4 @@ OC_App::register( array( "order" => 2, "id" => "files", "name" => "Files" ));
OC_App::addNavigationEntry( array( "id" => "files_index", "order" => 1, "href" => OC_Helper::linkTo( "files", "index.php" ), "icon" => OC_Helper::imagePath( "core", "places/home.svg" ), "name" => $l->t("Files") ));
?>
OC_Search::registerProvider('OC_Search_Provider_File');

View file

@ -387,39 +387,6 @@ function updateBreadcrumb(breadcrumbHtml) {
$('p.nav').empty().html(breadcrumbHtml);
}
function humanFileSize(bytes){
if( bytes < 1024 ){
return bytes+' B';
}
bytes = Math.round(bytes / 1024, 1 );
if( bytes < 1024 ){
return bytes+' kB';
}
bytes = Math.round( bytes / 1024, 1 );
if( bytes < 1024 ){
return bytes+' MB';
}
// Wow, heavy duty for owncloud
bytes = Math.round( bytes / 1024, 1 );
return bytes+' GB';
}
function simpleFileSize(bytes) {
mbytes = Math.round(bytes/(1024*1024/10))/10;
if(bytes == 0) { return '0'; }
else if(mbytes < 0.1) { return '< 0.1'; }
else if(mbytes > 1000) { return '> 1000'; }
else { return mbytes.toFixed(1); }
}
function formatDate(date){
var monthNames = [ t('files','January'), t('files','February'), t('files','March'), t('files','April'), t('files','May'), t('files','June'),
t('files','July'), t('files','August'), t('files','September'), t('files','October'), t('files','November'), t('files','December') ];
return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+date.getMinutes();
}
//options for file drag/dropp
var dragOptions={
distance: 20, revert: 'invalid', opacity: 0.7,

View file

@ -58,8 +58,8 @@ class OC_App{
$apps = OC_Appconfig::getApps();
foreach( $apps as $app ){
if( self::isEnabled( $app )){
if(is_file(OC::$SERVERROOT.'/apps/'.$app.'/appinfo/app.php')){
require( 'apps/'.$app.'/appinfo/app.php' );
if(is_file(OC::$APPSROOT.'/apps/'.$app.'/appinfo/app.php')){
require( $app.'/appinfo/app.php' );
}
}
}
@ -268,7 +268,7 @@ class OC_App{
if(is_file($appid)){
$file=$appid;
}else{
$file=OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/info.xml';
$file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
if(!is_file($file)){
return array();
}
@ -363,9 +363,9 @@ class OC_App{
*/
public static function getAllApps(){
$apps=array();
$dh=opendir(OC::$SERVERROOT.'/apps');
$dh=opendir(OC::$APPSROOT.'/apps');
while($file=readdir($dh)){
if(is_file(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/app.php')){
if(substr($file,0,1)!='.' and is_file(OC::$APPSROOT.'/apps/'.$file.'/appinfo/app.php')){
$apps[]=$file;
}
}
@ -396,11 +396,11 @@ class OC_App{
* @param string appid
*/
public static function updateApp($appid){
if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml')){
OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/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');
}
if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php')){
include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php';
if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php')){
include OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php';
}
}

View file

@ -62,6 +62,14 @@ class OC{
* the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty)
*/
public static $THIRDPARTYWEBROOT = '';
/**
* The installation path of the apps folder on the server (e.g. /srv/http/owncloud)
*/
public static $APPSROOT = '';
/**
* the root path of the apps folder for http requests (e.g. owncloud)
*/
public static $APPSWEBROOT = '';
/**
* SPL autoload
@ -136,6 +144,12 @@ class OC{
$_SERVER['PHP_AUTH_PW'] = strip_tags($password);
}
// register the stream wrappers
require_once('streamwrappers.php');
stream_wrapper_register("fakedir", "OC_FakeDirStream");
stream_wrapper_register('static', 'OC_StaticStreamWrapper');
stream_wrapper_register('close', 'OC_CloseStreamWrapper');
// calculate the documentroot
OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']);
OC::$SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-13));
@ -143,8 +157,17 @@ class OC{
$scriptName=$_SERVER["SCRIPT_NAME"];
if(substr($scriptName,-1)=='/'){
$scriptName.='index.php';
//make sure suburi follows the same rules as scriptName
if(substr(OC::$SUBURI,-9)!='index.php'){
if(substr(OC::$SUBURI,-1)!='/'){
OC::$SUBURI=OC::$SUBURI.'/';
}
OC::$SUBURI=OC::$SUBURI.'index.php';
}
}
OC::$WEBROOT=substr($scriptName,0,strlen($scriptName)-strlen(OC::$SUBURI));
OC::$WEBROOT=substr($scriptName,0,strlen($scriptName)-strlen(OC::$SUBURI));
// try a new way to detect the WEBROOT which is simpler and also works with the app directory outside the owncloud folder. let´s see if this works for everybody
// OC::$WEBROOT=substr(OC::$SERVERROOT,strlen(OC::$DOCUMENTROOT));
if(OC::$WEBROOT!='' and OC::$WEBROOT[0]!=='/'){
@ -159,22 +182,35 @@ class OC{
OC::$THIRDPARTYROOT=OC::$SERVERROOT;
OC::$THIRDPARTYWEBROOT=OC::$WEBROOT;
}elseif(file_exists(OC::$SERVERROOT.'/../3rdparty')){
$url_tmp=explode('/',OC::$WEBROOT);
$length=count($url_tmp);
unset($url_tmp[$length-1]);
OC::$THIRDPARTYWEBROOT=implode('/',$url_tmp);
$root_tmp=explode('/',OC::$SERVERROOT);
$length=count($root_tmp);
unset($root_tmp[$length-1]);
OC::$THIRDPARTYROOT=implode('/',$root_tmp);
OC::$THIRDPARTYWEBROOT=rtrim(dirname(OC::$WEBROOT), '/');
OC::$THIRDPARTYROOT=rtrim(dirname(OC::$SERVERROOT), '/');
}else{
echo("3rdparty directory not found! Please put the ownCloud 3rdparty folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file.");
exit;
}
// search the apps folder
if(file_exists(OC::$SERVERROOT.'/apps')){
OC::$APPSROOT=OC::$SERVERROOT;
OC::$APPSWEBROOT=OC::$WEBROOT;
}elseif(file_exists(OC::$SERVERROOT.'/../apps')){
OC::$APPSWEBROOT=rtrim(dirname(OC::$WEBROOT), '/');
OC::$APPSROOT=rtrim(dirname(OC::$SERVERROOT), '/');
}else{
echo("apps directory not found! Please put the ownCloud apps folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file.");
exit;
}
// set the right include path
set_include_path(OC::$SERVERROOT.'/lib'.PATH_SEPARATOR.OC::$SERVERROOT.'/config'.PATH_SEPARATOR.OC::$THIRDPARTYROOT.'/3rdparty'.PATH_SEPARATOR.get_include_path().PATH_SEPARATOR.OC::$SERVERROOT);
set_include_path(
OC::$SERVERROOT.'/lib'.PATH_SEPARATOR.
OC::$SERVERROOT.'/config'.PATH_SEPARATOR.
OC::$THIRDPARTYROOT.'/3rdparty'.PATH_SEPARATOR.
OC::$APPSROOT.PATH_SEPARATOR.
OC::$APPSROOT.'/apps'.PATH_SEPARATOR.
get_include_path().PATH_SEPARATOR.
OC::$SERVERROOT
);
// Redirect to installer if not installed
if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') {
@ -234,8 +270,10 @@ class OC{
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
OC_Util::addScript( "oc-dialogs" );
OC_Util::addScript( "js" );
OC_Util::addScript( "eventsource" );
OC_Util::addScript( "config" );
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
@ -261,6 +299,7 @@ class OC{
$_SESSION['user_id'] = '';
}
OC_User::useBackend( OC_Config::getValue( "userbackend", "database" ));
OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" ));
@ -277,9 +316,8 @@ class OC{
OC_App::loadApps();
}
// Last part: connect some hooks
OC_HOOK::connect('OC_User', 'post_createUser', 'OC_Connector_Sabre_Principal', 'addPrincipal');
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Connector_Sabre_Principal', 'deletePrincipal');
//make sure temporary files are cleaned up
register_shutdown_function(array('OC_Helper','cleanTmp'));
}
}
@ -302,15 +340,10 @@ if(!function_exists('get_temp_dir')) {
unlink($temp);
return dirname($temp);
}
if( $temp=sys_get_temp_dir()) return $temp;
return null;
}
}
OC::init();
require_once('fakedirstream.php');
// FROM search.php
new OC_Search_Provider_File();

View file

@ -23,6 +23,7 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic {
* @return bool
*/
protected function validateUserPass($username, $password){
OC_Util::setUpFS();//login hooks may need early access to the filesystem
if(OC_User::login($username,$password)){
OC_Util::setUpFS();
return true;

View file

@ -8,50 +8,6 @@
*/
class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend {
/**
* TODO: write doc
*/
public static function addPrincipal($params){
// Add the user
$uri = 'principals/'.$params['uid'];
$displayname = $params['uid'];
$query = OC_DB::prepare('INSERT INTO *PREFIX*principals (uri,displayname) VALUES(?,?)');
$query->execute(array($uri,$displayname));
// Add calendar and addressbook read and write support (sharing calendars)
$uri = 'principals/'.$params['uid'].'/calendar-proxy-read';
$displayname = null;
$query->execute(array($uri,$displayname));
$uri = 'principals/'.$params['uid'].'/calendar-proxy-write';
$query->execute(array($uri,$displayname));
$uri = 'principals/'.$params['uid'].'/addressbook-proxy-read';
$query->execute(array($uri,$displayname));
$uri = 'principals/'.$params['uid'].'/addressbook-proxy-write';
$query->execute(array($uri,$displayname));
return true;
}
/**
* TODO: write doc
*/
public static function deletePrincipal($params){
$query = OC_DB::prepare('SELECT * FROM *PREFIX*principals');
$result = $query->execute();
$deleteprincipal = OC_DB::prepare('DELETE FROM *PREFIX*principals WHERE id = ?');
$deletegroup = OC_DB::prepare('DELETE FROM *PREFIX*principalgroups WHERE principal_id = ? OR member_id = ?');
// We have to delete the principals and relations! Principals include
while($row = $result->fetchRow()){
// Checking if the principal is in the prefix
$array = explode('/',$row['uri']);
if ($array[1] != $params['uid']) continue;
$deleteprincipal->execute(array($row['id']));
$deletegroup->execute(array($row['id'],$row['id']));
}
return true;
}
/**
* Returns a list of principals based on a prefix.
*

View file

@ -316,8 +316,8 @@ class OC_DB {
// read file
$content = file_get_contents( $file );
// Make changes and save them to a temporary file
$file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' );
// Make changes and save them to an in-memory file
$file2 = 'static://db_scheme';
if($file2 == ''){
die('could not create tempfile in get_temp_dir() - aborting');
}
@ -331,7 +331,7 @@ class OC_DB {
// Try to create tables
$definition = self::$schema->parseDatabaseDefinitionFile( $file2 );
// Delete our temporary file
//clean up memory
unlink( $file2 );
// Die in case something went wrong
@ -371,8 +371,8 @@ class OC_DB {
return false;
}
// Make changes and save them to a temporary file
$file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' );
// Make changes and save them to an in-memory file
$file2 = 'static://db_scheme';
$content = str_replace( '*dbname*', $previousSchema['name'], $content );
$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't
@ -381,7 +381,7 @@ class OC_DB {
file_put_contents( $file2, $content );
$op = self::$schema->updateDatabase($file2, $previousSchema, array(), false);
// Delete our temporary file
//clean up memory
unlink( $file2 );
if (PEAR::isError($op)) {
@ -508,6 +508,21 @@ class OC_DB {
self::$connection->commit();
self::$inTransaction=false;
}
/**
* check if a result is an error, works with MDB2 and PDOException
* @param mixed $result
* @return bool
*/
public static function isError($result){
if(!$result){
return true;
}elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)){
return true;
}else{
return false;
}
}
}
/**
@ -527,11 +542,15 @@ class PDOStatementWrapper{
public function execute($input=array()){
$this->lastArguments=$input;
if(count($input)>0){
$this->statement->execute($input);
$result=$this->statement->execute($input);
}else{
$this->statement->execute();
$result=$this->statement->execute();
}
if($result){
return $this;
}else{
return false;
}
return $this;
}
/**

View file

@ -1,45 +0,0 @@
<?php
global $FAKEDIRS;
$FAKEDIRS=array();
class fakeDirStream{
private $name;
private $data;
private $index;
public function dir_opendir($path,$options){
global $FAKEDIRS;
$url=parse_url($path);
$this->name=substr($path,strlen('fakedir://'));
$this->index=0;
if(isset($FAKEDIRS[$this->name])){
$this->data=$FAKEDIRS[$this->name];
}else{
$this->data=array();
}
return true;
}
public function dir_readdir(){
if($this->index>=count($this->data)){
return false;
}
$filename=$this->data[$this->index];
$this->index++;
return $filename;
}
public function dir_closedir() {
$this->data=false;
$this->name='';
return true;
}
public function dir_rewinddir() {
$this->index=0;
return true;
}
}
stream_wrapper_register("fakedir", "fakeDirStream");

View file

@ -28,6 +28,8 @@
* It will try to keep the data up to date but changes from outside ownCloud can invalidate the cache
*/
class OC_FileCache{
private static $savedData=array();
/**
* get the filesystem info from the cache
* @param string path
@ -93,6 +95,14 @@ class OC_FileCache{
self::update($id,$data);
return;
}
if(isset(self::$savedData[$path])){
$data=array_merge($data,self::$savedData[$path]);
unset(self::$savedData[$path]);
}
if(!isset($data['size']) or !isset($data['mtime'])){//save incomplete data for the next time we write it
self::$savedData[$path]=$data;
return;
}
if(!isset($data['encrypted'])){
$data['encrypted']=false;
}
@ -101,9 +111,11 @@ class OC_FileCache{
}
$mimePart=dirname($data['mimetype']);
$user=OC_User::getUser();
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable) VALUES(?,?,?,?,?,?,?,?,?,?)');
$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable']));
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)');
$result=$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
}
/**
@ -128,7 +140,10 @@ class OC_FileCache{
$sql = 'UPDATE *PREFIX*fscache SET '.implode(' , ',$queryParts).' WHERE id=?';
$query=OC_DB::prepare($sql);
$query->execute($arguments);
$result=$query->execute($arguments);
if(OC_DB::isError($result)){
OC_Log::write('files','error while updating file('.$path.') in cache',OC_Log::ERROR);
}
}
/**
@ -262,11 +277,20 @@ class OC_FileCache{
*/
private static function getFileId($path){
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
if(OC_DB::isError($query)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
}
$result=$query->execute(array($path));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
}
$result=$result->fetchRow();
if(is_array($result)){
return $result['id'];
}else{
OC_Log::write('getFileId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
OC_Log::write('getFileId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
return -1;
}
}
@ -323,7 +347,29 @@ class OC_FileCache{
}
self::increaseSize(dirname($fullPath),$size-$cachedSize);
}
public static function getCached($path,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}else{
if($root=='/'){
$root='';
}
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
if(is_array($result)){
if(isset(self::$savedData[$path])){
$result=array_merge($result,self::$savedData[$path]);
}
return $result;
}else{
OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
return false;
}
}
private static function getCachedSize($path,$root){
if(!$root){
$root=OC_Filesystem::getRoot();
@ -332,6 +378,7 @@ class OC_FileCache{
$root='';
}
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
if($row=$result->fetchRow()){
@ -515,6 +562,9 @@ class OC_FileCache{
}
$view=new OC_FilesystemView($root);
}
if(!$view->file_exists($path)){
return false;
}
$mtime=$view->filemtime($path);
$isDir=$view->is_dir($path);
$path=$root.$path;

View file

@ -34,11 +34,12 @@
* A post-proxy recieves 2 arguments, the filepath and the result of the operation.
* The return calue of the post-proxy will be used as the new result of the operation
* The operations that have a post-proxy are
* file_get_contents, is_file, is_dir, file_exists, stat, is_readable, is_writable, filemtime, filectime, file_get_contents, getMimeType, hash, free_space and search
* file_get_contents, is_file, is_dir, file_exists, stat, is_readable, is_writable, fileatime, filemtime, filectime, file_get_contents, getMimeType, hash, fopen, free_space and search
*/
class OC_FileProxy{
private static $proxies=array();
public static $enabled=true;
/**
* check if this proxy implments a specific proxy operation
@ -83,16 +84,19 @@ class OC_FileProxy{
return $proxies;
}
public static function runPreProxies($operation,$filepath,$filepath2=null){
public static function runPreProxies($operation,&$filepath,&$filepath2=null){
if(!self::$enabled){
return true;
}
$proxies=self::getProxies($operation,false);
$operation='pre'.$operation;
foreach($proxies as $proxy){
if($filepath2){
if(!$proxy->$operation($filepath,$filepath2)){
if(!is_null($filepath2)){
if($proxy->$operation($filepath,$filepath2)===false){
return false;
}
}else{
if(!$proxy->$operation($filepath)){
if($proxy->$operation($filepath)===false){
return false;
}
}
@ -101,6 +105,9 @@ class OC_FileProxy{
}
public static function runPostProxies($operation,$path,$result){
if(!self::$enabled){
return $result;
}
$proxies=self::getProxies($operation,true);
$operation='post'.$operation;
foreach($proxies as $proxy){

View file

@ -23,33 +23,31 @@
/**
* Privde a common interface to all different storage options
*/
class OC_Filestorage{
abstract class OC_Filestorage{
public function __construct($parameters){}
public function mkdir($path){}
public function rmdir($path){}
public function opendir($path){}
public function is_dir($path){}
public function is_file($path){}
public function stat($path){}
public function filetype($path){}
public function filesize($path){}
public function is_readable($path){}
public function is_writable($path){}
public function file_exists($path){}
public function readfile($path){}
public function filectime($path){}
public function filemtime($path){}
public function file_get_contents($path){}
public function file_put_contents($path,$data){}
public function unlink($path){}
public function rename($path1,$path2){}
public function copy($path1,$path2){}
public function fopen($path,$mode){}
public function toTmpFile($path){}//copy the file to a temporary file, used for cross-storage file actions
public function fromTmpFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions
public function getMimeType($path){}
public function hash($type,$path,$raw){}
public function free_space($path){}
public function search($query){}
public function getLocalFile($path){}// get a path to a local version of the file, whether the original file is local or remote
abstract public function mkdir($path);
abstract public function rmdir($path);
abstract public function opendir($path);
abstract public function is_dir($path);
abstract public function is_file($path);
abstract public function stat($path);
abstract public function filetype($path);
abstract public function filesize($path);
abstract public function is_readable($path);
abstract public function is_writable($path);
abstract public function file_exists($path);
abstract public function filectime($path);
abstract public function filemtime($path);
abstract public function file_get_contents($path);
abstract public function file_put_contents($path,$data);
abstract public function unlink($path);
abstract public function rename($path1,$path2);
abstract public function copy($path1,$path2);
abstract public function fopen($path,$mode);
abstract public function getMimeType($path);
abstract public function hash($type,$path,$raw);
abstract public function free_space($path);
abstract public function search($query);
abstract public function touch($path, $mtime=null);
abstract public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote
}

151
lib/filestorage/common.php Normal file
View file

@ -0,0 +1,151 @@
<?php
/**
* ownCloud
*
* @author Michael Gapczynski
* @copyright 2012 Michael Gapczynski GapczynskiM@gmail.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/>.
*/
abstract class OC_Filestorage_Common extends OC_Filestorage {
public function __construct($parameters){}
// abstract public function mkdir($path);
// abstract public function rmdir($path);
// abstract public function opendir($path);
public function is_dir($path){
return $this->filetype($path)=='dir';
}
public function is_file($path){
return $this->filetype($path)=='file';
}
// abstract public function stat($path);
// abstract public function filetype($path);
public function filesize($path) {
if($this->is_dir($path)){
return 0;//by definition
}else{
$stat = $this->stat($path);
return $stat['size'];
}
}
// abstract public function is_readable($path);
// abstract public function is_writable($path);
// abstract public function file_exists($path);
public function filectime($path) {
$stat = $this->stat($path);
return $stat['ctime'];
}
public function filemtime($path) {
$stat = $this->stat($path);
return $stat['mtime'];
}
public function fileatime($path) {
$stat = $this->stat($path);
return $stat['atime'];
}
public function file_get_contents($path) {
$handle = $this->fopen($path, "r");
if(!$handle){
return false;
}
$size=$this->filesize($path);
if($size==0){
return '';
}
return fread($handle, $size);
}
public function file_put_contents($path,$data) {
$handle = $this->fopen($path, "w");
return fwrite($handle, $data);
}
// abstract public function unlink($path);
public function rename($path1,$path2){
if($this->copy($path1,$path2)){
return $this->unlink($path1);
}else{
return false;
}
}
public function copy($path1,$path2) {
$source=$this->fopen($path1,'r');
$target=$this->fopen($path2,'w');
$count=OC_Helper::streamCopy($source,$target);
return $count>0;
}
// abstract public function fopen($path,$mode);
public function getMimeType($path){
if(!$this->file_exists($path)){
return false;
}
if($this->is_dir($path)){
return 'httpd/unix-directory';
}
$source=$this->fopen($path,'r');
if(!$source){
return false;
}
$head=fread($source,8192);//8kb should suffice to determine a mimetype
$extention=substr($path,strrpos($path,'.'));
$tmpFile=OC_Helper::tmpFile($extention);
file_put_contents($tmpFile,$head);
$mime=OC_Helper::getMimeType($tmpFile);
unlink($tmpFile);
return $mime;
}
public function hash($type,$path,$raw){
$tmpFile=$this->getLocalFile();
$hash=hash($type,$tmpFile,$raw);
unlink($tmpFile);
return $hash;
}
// abstract public function free_space($path);
public function search($query){
return $this->searchInDir($query);
}
public function getLocalFile($path){
return $this->toTmpFile($path);
}
private function toTmpFile($path){//no longer in the storage api, still usefull here
$source=$this->fopen($path,'r');
if(!$source){
return false;
}
$extention=substr($path,strrpos($path,'.'));
$tmpFile=OC_Helper::tmpFile($extention);
$target=fopen($tmpFile,'w');
$count=OC_Helper::streamCopy($source,$target);
return $tmpFile;
}
// abstract public function touch($path, $mtime=null);
protected function searchInDir($query,$dir=''){
$files=array();
$dh=$this->opendir($dir);
if($dh){
while($item=readdir($dh)){
if ($item == '.' || $item == '..') continue;
if(strstr(strtolower($item),strtolower($query))!==false){
$files[]=$dir.'/'.$item;
}
if($this->is_dir($dir.'/'.$item)){
$files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item));
}
}
}
return $files;
}
}

View file

@ -0,0 +1,75 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 Robin Appelman icewind@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/>.
*
*/
/**
* test implementation for OC_FileStorage_Common with OC_FileStorage_Local
*/
class OC_Filestorage_CommonTest extends OC_Filestorage_Common{
/**
* underlying local storage used for missing functions
* @var OC_FileStorage_Local
*/
private $storage;
public function __construct($params){
$this->storage=new OC_Filestorage_Local($params);
}
public function mkdir($path){
return $this->storage->mkdir($path);
}
public function rmdir($path){
return $this->storage->rmdir($path);
}
public function opendir($path){
return $this->storage->opendir($path);
}
public function stat($path){
return $this->storage->stat($path);
}
public function filetype($path){
return $this->storage->filetype($path);
}
public function is_readable($path){
return $this->storage->is_readable($path);
}
public function is_writable($path){
return $this->storage->is_writable($path);
}
public function file_exists($path){
return $this->storage->file_exists($path);
}
public function unlink($path){
return $this->storage->unlink($path);
}
public function fopen($path,$mode){
return $this->storage->fopen($path,$mode);
}
public function free_space($path){
return $this->storage->free_space($path);
}
public function touch($path, $mtime=null){
return $this->storage->touch($path,$mtime);
}
}

View file

@ -20,36 +20,322 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
class OC_Filestorage_Google extends OC_Filestorage_Common {
private $auth;
require_once 'common.inc.php';
public function __construct($parameters) {
class OC_Filestorage_Google extends OC_Filestorage_Common {
private $datadir;
private $consumer;
private $oauth_token;
private $sig_method;
private $entries;
public function __construct($arguments) {
$this->datadir = $arguments['datadir'];
$consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous';
$consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous';
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
$this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']);
$this->sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->entries = array();
}
private function sendRequest($feedUri, $http_method, $postData = null) {
$feedUri = trim($feedUri);
// create an associative array from each key/value url query param pair.
$params = array();
$pieces = explode('?', $feedUri);
if (isset($pieces[1])) {
$params = explode_assoc('=', '&', $pieces[1]);
}
// urlencode each url parameter key/value pair
$tempStr = $pieces[0];
foreach ($params as $key => $value) {
$tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
}
$feedUri = preg_replace('/&/', '?', $tempStr, 1);
$req = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
$req->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
$auth_header = $req->to_header();
$result = send_signed_request($http_method, $feedUri, array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0'), $postData);
// TODO Return false if error is received
if (!$result) {
return false;
}
$result = explode('<', $result, 2);
$result = isset($result[1]) ? '<'.$result[1] : $result[0];
$dom = new DOMDocument();
$dom->loadXML($result);
return $dom;
}
private function getResource($path) {
if (array_key_exists($path, $this->entries)) {
return $this->entries[$path];
} else {
$title = basename($path);
$dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
// Check if request was successful and entry exists
if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
$this->entries[$path] = $entry;
return $entry;
}
return false;
}
}
private function getExtension($entry) {
$mimetype = $this->getMimeType('', $entry);
switch($mimetype) {
case 'httpd/unix-directory':
return '';
case 'application/vnd.oasis.opendocument.text':
return 'odt';
case 'application/vnd.oasis.opendocument.spreadsheet':
return 'ods';
case 'application/vnd.oasis.opendocument.presentation':
return 'pptx';
case 'text/html':
return 'html';
default:
return 'html';
}
}
public function mkdir($path) {
$dir = dirname($path);
// Check if path parent is root directory
if ($dir == '/' || $dir == '\.' || $dir == '.') {
$feedUri = 'https://docs.google.com/feeds/default/private/full';
// Get parent content link
} else if ($dom = $this->getResource(basename($dir))) {
$feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src');
}
if (isset($feedUri)) {
$title = basename($path);
// Construct post data
$postData = '<?xml version="1.0" encoding="UTF-8"?>';
$postData .= '<entry xmlns="http://www.w3.org/2005/Atom">';
$postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>';
$postData .= '<title>'.$title.'</title>';
$postData .= '</entry>';
if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) {
return true;
}
}
return false;
}
public function rmdir($path) {
return $this->unlink($path);
}
public function opendir($path) {
if ($path == '' || $path == '/') {
$next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents';
} else {
if ($entry = $this->getResource($path)) {
$next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
} else {
return false;
}
}
$files = array();
while ($next) {
$dom = $this->sendRequest($next, 'GET');
$links = $dom->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'next') {
$next = $link->getAttribute('src');
break;
} else {
$next = false;
}
}
$entries = $dom->getElementsByTagName('entry');
foreach ($entries as $entry) {
$name = $entry->getElementsByTagName('title')->item(0)->nodeValue;
// Google Docs resources don't always include extensions in title
if (!strpos($name, '.')) {
$name .= '.'.$this->getExtension($entry);
}
$files[] = $name;
// Cache entry for future use
$this->entries[$name] = $entry;
}
}
OC_FakeDirStream::$dirs['google'] = $files;
return opendir('fakedir://google');
}
public function stat($path) {
if ($path == '' || $path == '/') {
$stat['size'] = $this->free_space($path);
$stat['atime'] = time();
$stat['mtime'] = time();
$stat['ctime'] = time();
} else if ($entry = $this->getResource($path)) {
// NOTE: Native resources don't have a file size
$stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
$stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
$stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue);
$stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue);
}
return $stat;
}
public function filetype($path) {
if ($path == '' || $path == '/') {
return 'dir';
} else if ($entry = $this->getResource($path)) {
$categories = $entry->getElementsByTagName('category');
foreach ($categories as $category) {
if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
$type = $category->getAttribute('label');
if (strlen(strstr($type, 'folder')) > 0) {
return 'dir';
} else {
return 'file';
}
}
}
}
return false;
}
public function is_readable($path) {
return true;
}
public function is_writable($path) {
if ($path == '' || $path == '/') {
return true;
} else if ($entry = $this->getResource($path)) {
// Check if edit or edit-media links exist
$links = $entry->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'edit') {
return true;
} else if ($link->getAttribute('rel') == 'edit-media') {
return true;
}
}
}
return false;
}
public function file_exists($path) {
if ($path == '' || $path == '/') {
return true;
} else if ($this->getResource($path)) {
return true;
}
return false;
}
public function unlink($path) {
// Get resource self link to trash resource
if ($entry = $this->getResource($path)) {
$links = $entry->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'self') {
$feedUri = $link->getAttribute('href');
}
}
}
if (isset($feedUri)) {
$this->sendRequest($feedUri, 'DELETE');
return true;
}
return false;
}
public function rename($path1, $path2) {
// TODO Add support for moving to different collections
// Get resource edit link to rename resource
if ($entry = $this->getResource($path1)) {
$etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag');
$links = $entry->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'edit') {
$feedUri = $link->getAttribute('href');
}
}
}
if (isset($etag) && isset($feedUri)) {
$title = basename($path2);
// Construct post data
$postData = '<?xml version="1.0" encoding="UTF-8"?>';
$postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>';
$postData .= '<title>'.$title.'</title>';
$postData .= '</entry>';
$this->sendRequest($feedUri, 'PUT', $postData);
return true;
}
return false;
}
public function fopen($path, $mode) {
if ($entry = $this->getResource($path)) {
$extension = $this->getExtension($path);
$downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
// TODO Non-native documents don't need these additional parameters
$downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
}
}
public function getMimeType($path, $entry = null) {
if ($entry == null) {
if ($path == '' || $path == '/') {
return 'httpd/unix-directory';
} else {
$entry = $this->getResource($path);
}
}
if ($entry) {
$mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type');
// Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype
// Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype
if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml') {
$categories = $entry->getElementsByTagName('category');
foreach ($categories as $category) {
if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
$type = $category->getAttribute('label');
if (strlen(strstr($type, 'folder')) > 0) {
return 'httpd/unix-directory';
} else if (strlen(strstr($type, 'document')) > 0) {
return 'application/vnd.oasis.opendocument.text';
} else if (strlen(strstr($type, 'spreadsheet')) > 0) {
return 'application/vnd.oasis.opendocument.spreadsheet';
} else if (strlen(strstr($type, 'presentation')) > 0) {
return 'application/vnd.oasis.opendocument.presentation';
} else if (strlen(strstr($type, 'drawing')) > 0) {
return 'application/vnd.oasis.opendocument.graphics';
} else {
// If nothing matches return text/html, all native Google Docs resources can be exported as text/html
return 'text/html';
}
}
}
}
return $mimetype;
}
return false;
}
public function free_space($path) {
if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) {
// NOTE: Native Google Docs resources don't count towards quota
$total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue;
$used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
return $total - $used;
}
return false;
}
public function search($query) {
}
private function connect() {
}
public function mkdir($path){}
public function rmdir($path){}
public function opendir($path){}
public function is_dir($path){}
public function is_file($path){}
public function stat($path){}
public function filetype($path){}
public function is_readable($path){}
public function is_writable($path){}
public function file_exists($path){}
public function unlink($path){}
public function rename($path1,$path2){}
public function fopen($path,$mode){}
public function toTmpFile($path){}
public function fromTmpFile($tmpPath,$path){}
public function fromUploadedFile($tmpPath,$path){}
public function getMimeType($path){}
public function hash($type,$path,$raw){}
public function free_space($path){}
public function search($query){}
public function getLocalFile($path){}
}

Some files were not shown because too many files have changed in this diff Show more