summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.jshintrc2
-rw-r--r--.scrutinizer.yml23
m---------3rdparty0
-rw-r--r--apps/files/ajax/delete.php2
-rw-r--r--apps/files/ajax/move.php2
-rw-r--r--apps/files/ajax/rawlist.php59
-rw-r--r--apps/files/js/admin.js19
-rw-r--r--apps/files/js/file-upload.js1015
-rw-r--r--apps/files/js/filelist.js17
-rw-r--r--apps/files/js/files.js11
-rw-r--r--apps/files/templates/part.list.php16
-rw-r--r--apps/files/tests/js/fileUploadSpec.js127
-rw-r--r--apps/files/tests/js/filesSpec.js35
-rw-r--r--apps/files_encryption/js/settings-admin.js22
-rw-r--r--apps/files_encryption/lib/proxy.php41
-rw-r--r--apps/files_encryption/lib/session.php8
-rw-r--r--apps/files_encryption/lib/stream.php3
-rw-r--r--apps/files_encryption/lib/util.php9
-rw-r--r--apps/files_encryption/tests/proxy.php20
-rwxr-xr-xapps/files_encryption/tests/util.php4
-rw-r--r--apps/files_external/js/settings.js12
-rwxr-xr-xapps/files_external/lib/config.php46
-rw-r--r--apps/files_external/lib/webdav.php193
-rwxr-xr-xapps/files_external/personal.php5
-rw-r--r--apps/files_external/settings.php18
-rw-r--r--apps/files_external/templates/settings.php18
-rw-r--r--apps/files_sharing/appinfo/routes.php1
-rw-r--r--apps/files_sharing/js/share.js21
-rw-r--r--apps/files_sharing/lib/api.php12
-rw-r--r--apps/files_sharing/lib/cache.php3
-rw-r--r--apps/files_sharing/lib/share/file.php3
-rw-r--r--apps/files_sharing/templates/authenticate.php5
-rw-r--r--apps/files_sharing/tests/api.php68
-rw-r--r--apps/files_sharing/tests/base.php1
-rw-r--r--apps/user_ldap/lib/helper.php2
-rw-r--r--apps/user_ldap/user_proxy.php17
-rwxr-xr-xconfig/config.sample.php3
-rw-r--r--core/css/apps.css3
-rw-r--r--core/css/icons.css15
-rw-r--r--core/css/styles.css17
-rw-r--r--core/img/logo-mail.gifbin2196 -> 1191 bytes
-rw-r--r--core/js/config.php6
-rw-r--r--core/js/core.json1
-rw-r--r--core/js/jquery.avatar.js41
-rw-r--r--core/js/js.js62
-rw-r--r--core/js/router.js81
-rw-r--r--core/js/setup.js2
-rw-r--r--core/js/share.js4
-rw-r--r--core/js/tags.js18
-rw-r--r--core/js/tests/specHelper.js16
-rw-r--r--core/js/tests/specs/coreSpec.js23
-rw-r--r--core/lostpassword/controller.php2
-rw-r--r--core/routes.php2
-rw-r--r--core/templates/installation.php8
-rw-r--r--core/templates/mail.php22
-rw-r--r--lib/base.php23
-rw-r--r--lib/private/api.php23
-rw-r--r--lib/private/app.php2
-rw-r--r--lib/private/config.php2
-rw-r--r--lib/private/connector/sabre/directory.php4
-rw-r--r--lib/private/connector/sabre/objecttree.php3
-rw-r--r--lib/private/db/mdb2schemamanager.php3
-rw-r--r--lib/private/db/mdb2schemareader.php2
-rw-r--r--lib/private/defaults.php21
-rw-r--r--lib/private/files.php213
-rw-r--r--lib/private/files/cache/cache.php10
-rw-r--r--lib/private/files/cache/homecache.php9
-rw-r--r--lib/private/files/fileinfo.php16
-rw-r--r--lib/private/files/filesystem.php5
-rw-r--r--lib/private/files/storage/common.php24
-rw-r--r--lib/private/files/storage/wrapper/quota.php5
-rw-r--r--lib/private/files/view.php5
-rw-r--r--lib/private/helper.php4
-rw-r--r--lib/private/image.php38
-rw-r--r--lib/private/installer.php2
-rw-r--r--lib/private/l10n.php28
-rw-r--r--lib/private/mimetypes.list.php1
-rw-r--r--lib/private/ocs/cloud.php16
-rwxr-xr-xlib/private/preview.php246
-rw-r--r--lib/private/preview/movies.php2
-rw-r--r--lib/private/preview/office-cl.php4
-rw-r--r--lib/private/preview/office.php35
-rw-r--r--lib/private/preview/pdf.php49
-rw-r--r--lib/private/preview/svg.php58
-rwxr-xr-xlib/private/request.php78
-rw-r--r--lib/private/router.php24
-rw-r--r--lib/private/setup.php2
-rw-r--r--lib/private/template/base.php2
-rw-r--r--lib/public/files/fileinfo.php2
-rw-r--r--lib/public/share.php16
-rwxr-xr-xsettings/admin.php10
-rw-r--r--settings/admin/controller.php123
-rw-r--r--settings/ajax/decryptall.php2
-rw-r--r--settings/css/settings.css19
-rw-r--r--settings/js/admin.js42
-rw-r--r--settings/js/apps.js24
-rw-r--r--settings/js/personal.js32
-rw-r--r--settings/js/users.js9
-rw-r--r--settings/routes.php8
-rw-r--r--settings/templates/admin.php103
-rw-r--r--settings/templates/personal.php4
-rw-r--r--tests/data/db_structure.xml15
-rw-r--r--tests/data/db_structure2.xml15
-rw-r--r--tests/lib/appframework/http/ResponseTest.php2
-rw-r--r--tests/lib/files/cache/scanner.php26
-rw-r--r--tests/lib/files/cache/updater.php85
-rw-r--r--tests/lib/files/etagtest.php6
-rw-r--r--tests/lib/files/storage/wrapper/quota.php16
-rw-r--r--tests/lib/files/view.php2
-rw-r--r--tests/lib/request.php137
110 files changed, 2456 insertions, 1387 deletions
diff --git a/.jshintrc b/.jshintrc
index f40dd22b5fd..90cec5c5961 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -1,5 +1,5 @@
{
- "camelCase": true,
+ "camelcase": true,
"eqeqeq": true,
"immed": true,
"latedef": false,
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
new file mode 100644
index 00000000000..4473cf9056d
--- /dev/null
+++ b/.scrutinizer.yml
@@ -0,0 +1,23 @@
+filter:
+ excluded_paths:
+ - '3rdparty/*'
+ - 'apps/*/3rdparty/*'
+ - 'l10n/*'
+ - 'core/l10n/*'
+ - 'apps/*/l10n/*'
+ - 'lib/l10n/*'
+ - 'core/js/tests/lib/*.js'
+ - 'core/js/jquery-1.10.0.min.js'
+ - 'core/js/jquery-migrate-1.2.1.min.js'
+ - 'core/js/jquery-showpassword.js'
+ - 'core/js/jquery-tipsy.js'
+ - 'core/js/jquery.infieldlabel.js'
+ - 'core/js/jquery-ui-1.10.0.custom.js'
+ - 'core/js/jquery.inview.js'
+ - 'core/js/jquery.placeholder.js'
+
+
+imports:
+ - javascript
+ - php
+
diff --git a/3rdparty b/3rdparty
-Subproject 478de4b756f3729f762d838b29f69f2a40e5f4f
+Subproject 184f0a59f87c590ee7e89ced401205a87f21395
diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php
index 69f859daa97..99f49188384 100644
--- a/apps/files/ajax/delete.php
+++ b/apps/files/ajax/delete.php
@@ -9,7 +9,7 @@ OCP\JSON::callCheck();
// Get data
$dir = stripslashes($_POST["dir"]);
$files = isset($_POST["file"]) ? $_POST["file"] : $_POST["files"];
-$allFiles = isset($_POST["allfiles"]) ? $_POST["allfiles"] : $_POST["allfiles"];
+$allFiles = isset($_POST["allfiles"]) ? $_POST["allfiles"] : false;
if ($allFiles === 'true') {
$allFiles = true;
}
diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php
index 93063e52eb0..04a260265c2 100644
--- a/apps/files/ajax/move.php
+++ b/apps/files/ajax/move.php
@@ -18,7 +18,7 @@ if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
exit;
}
-if ($dir != '' || $file != 'Shared') {
+if ($target != '' || strtolower($file) != 'shared') {
$targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file);
$sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {
diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php
index 40da32b223a..89c21a172fc 100644
--- a/apps/files/ajax/rawlist.php
+++ b/apps/files/ajax/rawlist.php
@@ -1,12 +1,12 @@
<?php
// only need filesystem apps
-$RUNTIME_APPTYPES=array('filesystem');
+$RUNTIME_APPTYPES = array('filesystem');
OCP\JSON::checkLoggedIn();
// Load the files
-$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
$mimetypes = isset($_GET['mimetypes']) ? json_decode($_GET['mimetypes'], true) : '';
// Clean up duplicates from array and deal with non-array requests
@@ -18,43 +18,40 @@ if (is_array($mimetypes)) {
// make filelist
$files = array();
+/**
+ * @var \OCP\Files\FileInfo[] $files
+ */
// If a type other than directory is requested first load them.
-if($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) {
- foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, 'httpd/unix-directory' ) as $file ) {
- $file['directory'] = $dir;
- $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']);
- $file["date"] = OCP\Util::formatDate($file["mtime"]);
- $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file);
- $files[] = $file;
- }
+if ($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) {
+ $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, 'httpd/unix-directory'));
}
if (is_array($mimetypes) && count($mimetypes)) {
foreach ($mimetypes as $mimetype) {
- foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $file ) {
- $file['directory'] = $dir;
- $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']);
- $file["date"] = OCP\Util::formatDate($file["mtime"]);
- $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file);
- $files[] = $file;
- }
+ $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, $mimetype));
}
} else {
- foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $file ) {
- $file['directory'] = $dir;
- $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']);
- $file["date"] = OCP\Util::formatDate($file["mtime"]);
- $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file);
- $files[] = $file;
- }
+ $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir));
+}
+
+$result = array();
+foreach ($files as $file) {
+ $fileData = array();
+ $fileData['directory'] = $dir;
+ $fileData['name'] = $file->getName();
+ $fileData['type'] = $file->getType();
+ $fileData['path'] = $file['path'];
+ $fileData['id'] = $file->getId();
+ $fileData['size'] = $file->getSize();
+ $fileData['mtime'] = $file->getMtime();
+ $fileData['mimetype'] = $file->getMimetype();
+ $fileData['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file->getMimetype());
+ $fileData["date"] = OCP\Util::formatDate($file->getMtime());
+ $fileData['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file);
+ $result[] = $fileData;
}
// Sort by name
-usort($files, function ($a, $b) {
- if ($a['name'] === $b['name']) {
- return 0;
- }
- return ($a['name'] < $b['name']) ? -1 : 1;
-});
+usort($result, array('\OCA\Files\Helper', 'fileCmp'));
-OC_JSON::success(array('data' => $files));
+OC_JSON::success(array('data' => $result));
diff --git a/apps/files/js/admin.js b/apps/files/js/admin.js
index f735079fcbe..842b73c0cae 100644
--- a/apps/files/js/admin.js
+++ b/apps/files/js/admin.js
@@ -8,19 +8,22 @@
*
*/
-function switchPublicFolder()
-{
+function switchPublicFolder() {
var publicEnable = $('#publicEnable').is(':checked');
- var sharingaimGroup = $('input:radio[name=sharingaim]'); //find all radiobuttons of that group
+ // find all radiobuttons of that group
+ var sharingaimGroup = $('input:radio[name=sharingaim]');
$.each(sharingaimGroup, function(index, sharingaimItem) {
- sharingaimItem.disabled = !publicEnable; //set all buttons to the correct state
+ // set all buttons to the correct state
+ sharingaimItem.disabled = !publicEnable;
});
}
-$(document).ready(function(){
- switchPublicFolder(); // Execute the function after loading DOM tree
- $('#publicEnable').click(function(){
- switchPublicFolder(); // To get rid of onClick()
+$(document).ready(function() {
+ // Execute the function after loading DOM tree
+ switchPublicFolder();
+ $('#publicEnable').click(function() {
+ // To get rid of onClick()
+ switchPublicFolder();
});
$('#allowZipDownload').bind('change', function() {
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index f962a7044a8..ea4061c9b0b 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -82,7 +82,7 @@ OC.Upload = {
*/
isProcessing:function() {
var count = 0;
-
+
jQuery.each(this._uploads,function(i, data) {
if (data.state() === 'pending') {
count++;
@@ -177,549 +177,556 @@ OC.Upload = {
checkExistingFiles: function (selection, callbacks) {
// TODO check filelist before uploading and show dialog on conflicts, use callbacks
callbacks.onNoConflicts(selection);
- }
-};
+ },
-$(document).ready(function() {
+ init: function() {
+ if ( $('#file_upload_start').exists() && $('#file_upload_start').is(':visible')) {
- if ( $('#file_upload_start').exists() ) {
-
- var file_upload_param = {
- dropZone: $('#content'), // restrict dropZone to content div
- autoUpload: false,
- sequentialUploads: true,
- //singleFileUploads is on by default, so the data.files array will always have length 1
- /**
- * on first add of every selection
- * - check all files of originalFiles array with files in dir
- * - on conflict show dialog
- * - skip all -> remember as single skip action for all conflicting files
- * - replace all -> remember as single replace action for all conflicting files
- * - choose -> show choose dialog
- * - mark files to keep
- * - when only existing -> remember as single skip action
- * - when only new -> remember as single replace action
- * - when both -> remember as single autorename action
- * - start uploading selection
- * @param {object} e
- * @param {object} data
- * @returns {boolean}
- */
- add: function(e, data) {
- OC.Upload.log('add', e, data);
- var that = $(this);
-
- // we need to collect all data upload objects before starting the upload so we can check their existence
- // and set individual conflict actions. unfortunately there is only one variable that we can use to identify
- // the selection a data upload is part of, so we have to collect them in data.originalFiles
- // turning singleFileUploads off is not an option because we want to gracefully handle server errors like
- // already exists
-
- // create a container where we can store the data objects
- if ( ! data.originalFiles.selection ) {
- // initialize selection and remember number of files to upload
- data.originalFiles.selection = {
- uploads: [],
- filesToUpload: data.originalFiles.length,
- totalBytes: 0
- };
- }
- var selection = data.originalFiles.selection;
-
- // add uploads
- if ( selection.uploads.length < selection.filesToUpload ) {
- // remember upload
- selection.uploads.push(data);
- }
-
- //examine file
- var file = data.files[0];
- try {
- // FIXME: not so elegant... need to refactor that method to return a value
- Files.isFileNameValid(file.name);
- }
- catch (errorMessage) {
- data.textStatus = 'invalidcharacters';
- data.errorThrown = errorMessage;
- }
-
- if (file.type === '' && file.size === 4096) {
- data.textStatus = 'dirorzero';
- data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes',
- {filename: file.name}
- );
- }
-
- // add size
- selection.totalBytes += file.size;
-
- // check PHP upload limit
- if (selection.totalBytes > $('#upload_limit').val()) {
- data.textStatus = 'sizeexceedlimit';
- data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', {
- 'size1': humanFileSize(selection.totalBytes),
- 'size2': humanFileSize($('#upload_limit').val())
- });
- }
+ var file_upload_param = {
+ dropZone: $('#content'), // restrict dropZone to content div
+ autoUpload: false,
+ sequentialUploads: true,
+ //singleFileUploads is on by default, so the data.files array will always have length 1
+ /**
+ * on first add of every selection
+ * - check all files of originalFiles array with files in dir
+ * - on conflict show dialog
+ * - skip all -> remember as single skip action for all conflicting files
+ * - replace all -> remember as single replace action for all conflicting files
+ * - choose -> show choose dialog
+ * - mark files to keep
+ * - when only existing -> remember as single skip action
+ * - when only new -> remember as single replace action
+ * - when both -> remember as single autorename action
+ * - start uploading selection
+ * @param {object} e
+ * @param {object} data
+ * @returns {boolean}
+ */
+ add: function(e, data) {
+ OC.Upload.log('add', e, data);
+ var that = $(this);
+ var freeSpace;
- // check free space
- if (selection.totalBytes > $('#free_space').val()) {
- data.textStatus = 'notenoughspace';
- data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', {
- 'size1': humanFileSize(selection.totalBytes),
- 'size2': humanFileSize($('#free_space').val())
- });
- }
-
- // end upload for whole selection on error
- if (data.errorThrown) {
- // trigger fileupload fail
- var fu = that.data('blueimp-fileupload') || that.data('fileupload');
- fu._trigger('fail', e, data);
- return false; //don't upload anything
- }
+ // we need to collect all data upload objects before starting the upload so we can check their existence
+ // and set individual conflict actions. unfortunately there is only one variable that we can use to identify
+ // the selection a data upload is part of, so we have to collect them in data.originalFiles
+ // turning singleFileUploads off is not an option because we want to gracefully handle server errors like
+ // already exists
- // check existing files when all is collected
- if ( selection.uploads.length >= selection.filesToUpload ) {
-
- //remove our selection hack:
- delete data.originalFiles.selection;
-
- var callbacks = {
-
- onNoConflicts: function (selection) {
- $.each(selection.uploads, function(i, upload) {
- upload.submit();
- });
- },
- onSkipConflicts: function (selection) {
- //TODO mark conflicting files as toskip
- },
- onReplaceConflicts: function (selection) {
- //TODO mark conflicting files as toreplace
- },
- onChooseConflicts: function (selection) {
- //TODO mark conflicting files as chosen
- },
- onCancel: function (selection) {
- $.each(selection.uploads, function(i, upload) {
- upload.abort();
- });
- }
- };
+ // create a container where we can store the data objects
+ if ( ! data.originalFiles.selection ) {
+ // initialize selection and remember number of files to upload
+ data.originalFiles.selection = {
+ uploads: [],
+ filesToUpload: data.originalFiles.length,
+ totalBytes: 0
+ };
+ }
+ var selection = data.originalFiles.selection;
- OC.Upload.checkExistingFiles(selection, callbacks);
-
- }
+ // add uploads
+ if ( selection.uploads.length < selection.filesToUpload ) {
+ // remember upload
+ selection.uploads.push(data);
+ }
- return true; // continue adding files
- },
- /**
- * called after the first add, does NOT have the data param
- * @param {object} e
- */
- start: function(e) {
- OC.Upload.log('start', e, null);
- },
- submit: function(e, data) {
- OC.Upload.rememberUpload(data);
- if ( ! data.formData ) {
- // noone set update parameters, we set the minimum
- data.formData = {
- requesttoken: oc_requesttoken,
- dir: $('#dir').val()
- };
- }
- },
- fail: function(e, data) {
- OC.Upload.log('fail', e, data);
- if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) {
- if (data.textStatus === 'abort') {
- OC.Notification.show(t('files', 'Upload cancelled.'));
- } else {
- // HTTP connection problem
- OC.Notification.show(data.errorThrown);
- if (data.result) {
- var result = JSON.parse(data.result);
- if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') {
- // abort upload of next files if any
- OC.Upload.cancelUploads();
+ //examine file
+ var file = data.files[0];
+ try {
+ // FIXME: not so elegant... need to refactor that method to return a value
+ Files.isFileNameValid(file.name, FileList.getCurrentDirectory());
+ }
+ catch (errorMessage) {
+ data.textStatus = 'invalidcharacters';
+ data.errorThrown = errorMessage;
+ }
+
+ if (file.type === '' && file.size === 4096) {
+ data.textStatus = 'dirorzero';
+ data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes',
+ {filename: file.name}
+ );
+ }
+
+ // add size
+ selection.totalBytes += file.size;
+
+ // check PHP upload limit
+ if (selection.totalBytes > $('#upload_limit').val()) {
+ data.textStatus = 'sizeexceedlimit';
+ data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', {
+ 'size1': humanFileSize(selection.totalBytes),
+ 'size2': humanFileSize($('#upload_limit').val())
+ });
+ }
+
+ // check free space
+ freeSpace = $('#free_space').val();
+ if (freeSpace >= 0 && selection.totalBytes > freeSpace) {
+ data.textStatus = 'notenoughspace';
+ data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', {
+ 'size1': humanFileSize(selection.totalBytes),
+ 'size2': humanFileSize($('#free_space').val())
+ });
+ }
+
+ // end upload for whole selection on error
+ if (data.errorThrown) {
+ // trigger fileupload fail
+ var fu = that.data('blueimp-fileupload') || that.data('fileupload');
+ fu._trigger('fail', e, data);
+ return false; //don't upload anything
+ }
+
+ // check existing files when all is collected
+ if ( selection.uploads.length >= selection.filesToUpload ) {
+
+ //remove our selection hack:
+ delete data.originalFiles.selection;
+
+ var callbacks = {
+
+ onNoConflicts: function (selection) {
+ $.each(selection.uploads, function(i, upload) {
+ upload.submit();
+ });
+ },
+ onSkipConflicts: function (selection) {
+ //TODO mark conflicting files as toskip
+ },
+ onReplaceConflicts: function (selection) {
+ //TODO mark conflicting files as toreplace
+ },
+ onChooseConflicts: function (selection) {
+ //TODO mark conflicting files as chosen
+ },
+ onCancel: function (selection) {
+ $.each(selection.uploads, function(i, upload) {
+ upload.abort();
+ });
+ }
+ };
+
+ OC.Upload.checkExistingFiles(selection, callbacks);
+
+ }
+
+ return true; // continue adding files
+ },
+ /**
+ * called after the first add, does NOT have the data param
+ * @param {object} e
+ */
+ start: function(e) {
+ OC.Upload.log('start', e, null);
+ },
+ submit: function(e, data) {
+ OC.Upload.rememberUpload(data);
+ if ( ! data.formData ) {
+ // noone set update parameters, we set the minimum
+ data.formData = {
+ requesttoken: oc_requesttoken,
+ dir: $('#dir').val()
+ };
+ }
+ },
+ fail: function(e, data) {
+ OC.Upload.log('fail', e, data);
+ if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) {
+ if (data.textStatus === 'abort') {
+ OC.Notification.show(t('files', 'Upload cancelled.'));
+ } else {
+ // HTTP connection problem
+ OC.Notification.show(data.errorThrown);
+ if (data.result) {
+ var result = JSON.parse(data.result);
+ if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') {
+ // abort upload of next files if any
+ OC.Upload.cancelUploads();
+ }
}
}
+ //hide notification after 10 sec
+ setTimeout(function() {
+ OC.Notification.hide();
+ }, 10000);
}
- //hide notification after 10 sec
- setTimeout(function() {
- OC.Notification.hide();
- }, 10000);
- }
- OC.Upload.deleteUpload(data);
- },
- /**
- * called for every successful upload
- * @param {object} e
- * @param {object} data
- */
- done:function(e, data) {
- OC.Upload.log('done', e, data);
- // handle different responses (json or body from iframe for ie)
- var response;
- if (typeof data.result === 'string') {
- response = data.result;
- } else {
- //fetch response from iframe
- response = data.result[0].body.innerText;
- }
- var result=$.parseJSON(response);
-
- delete data.jqXHR;
-
- if (result.status === 'error' && result.data && result.data.message){
- data.textStatus = 'servererror';
- data.errorThrown = result.data.message;
- var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
- fu._trigger('fail', e, data);
- } else if (typeof result[0] === 'undefined') {
- data.textStatus = 'servererror';
- data.errorThrown = t('files', 'Could not get result from server.');
- var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
- fu._trigger('fail', e, data);
- } else if (result[0].status === 'existserror') {
- //show "file already exists" dialog
- var original = result[0];
- var replacement = data.files[0];
- var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
- OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu);
- } else if (result[0].status !== 'success') {
- //delete data.jqXHR;
- data.textStatus = 'servererror';
- data.errorThrown = result[0].data.message; // error message has been translated on server
- var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
- fu._trigger('fail', e, data);
+ OC.Upload.deleteUpload(data);
+ },
+ /**
+ * called for every successful upload
+ * @param {object} e
+ * @param {object} data
+ */
+ done:function(e, data) {
+ OC.Upload.log('done', e, data);
+ // handle different responses (json or body from iframe for ie)
+ var response;
+ if (typeof data.result === 'string') {
+ response = data.result;
+ } else {
+ //fetch response from iframe
+ response = data.result[0].body.innerText;
+ }
+ var result=$.parseJSON(response);
+
+ delete data.jqXHR;
+
+ if (result.status === 'error' && result.data && result.data.message){
+ data.textStatus = 'servererror';
+ data.errorThrown = result.data.message;
+ var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+ fu._trigger('fail', e, data);
+ } else if (typeof result[0] === 'undefined') {
+ data.textStatus = 'servererror';
+ data.errorThrown = t('files', 'Could not get result from server.');
+ var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+ fu._trigger('fail', e, data);
+ } else if (result[0].status === 'existserror') {
+ //show "file already exists" dialog
+ var original = result[0];
+ var replacement = data.files[0];
+ var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+ OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu);
+ } else if (result[0].status !== 'success') {
+ //delete data.jqXHR;
+ data.textStatus = 'servererror';
+ data.errorThrown = result[0].data.message; // error message has been translated on server
+ var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+ fu._trigger('fail', e, data);
+ }
+ },
+ /**
+ * called after last upload
+ * @param {object} e
+ * @param {object} data
+ */
+ stop: function(e, data) {
+ OC.Upload.log('stop', e, data);
}
- },
- /**
- * called after last upload
- * @param {object} e
- * @param {object} data
- */
- stop: function(e, data) {
- OC.Upload.log('stop', e, data);
- }
- };
+ };
- // initialize jquery fileupload (blueimp)
- var fileupload = $('#file_upload_start').fileupload(file_upload_param);
- window.file_upload_param = fileupload;
+ // initialize jquery fileupload (blueimp)
+ var fileupload = $('#file_upload_start').fileupload(file_upload_param);
+ window.file_upload_param = fileupload;
- if (supportAjaxUploadWithProgress()) {
+ if (supportAjaxUploadWithProgress()) {
+
+ // add progress handlers
+ fileupload.on('fileuploadadd', function(e, data) {
+ OC.Upload.log('progress handle fileuploadadd', e, data);
+ //show cancel button
+ //if (data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie?
+ // $('#uploadprogresswrapper input.stop').show();
+ //}
+ });
+ // add progress handlers
+ fileupload.on('fileuploadstart', function(e, data) {
+ OC.Upload.log('progress handle fileuploadstart', e, data);
+ $('#uploadprogresswrapper input.stop').show();
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
+ });
+ fileupload.on('fileuploadprogress', function(e, data) {
+ OC.Upload.log('progress handle fileuploadprogress', e, data);
+ //TODO progressbar in row
+ });
+ fileupload.on('fileuploadprogressall', function(e, data) {
+ OC.Upload.log('progress handle fileuploadprogressall', e, data);
+ var progress = (data.loaded / data.total) * 100;
+ $('#uploadprogressbar').progressbar('value', progress);
+ });
+ fileupload.on('fileuploadstop', function(e, data) {
+ OC.Upload.log('progress handle fileuploadstop', e, data);
- // add progress handlers
- fileupload.on('fileuploadadd', function(e, data) {
- OC.Upload.log('progress handle fileuploadadd', e, data);
- //show cancel button
- //if (data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie?
- // $('#uploadprogresswrapper input.stop').show();
- //}
- });
- // add progress handlers
- fileupload.on('fileuploadstart', function(e, data) {
- OC.Upload.log('progress handle fileuploadstart', e, data);
- $('#uploadprogresswrapper input.stop').show();
- $('#uploadprogressbar').progressbar({value:0});
- $('#uploadprogressbar').fadeIn();
- });
- fileupload.on('fileuploadprogress', function(e, data) {
- OC.Upload.log('progress handle fileuploadprogress', e, data);
- //TODO progressbar in row
- });
- fileupload.on('fileuploadprogressall', function(e, data) {
- OC.Upload.log('progress handle fileuploadprogressall', e, data);
- var progress = (data.loaded / data.total) * 100;
- $('#uploadprogressbar').progressbar('value', progress);
- });
- fileupload.on('fileuploadstop', function(e, data) {
- OC.Upload.log('progress handle fileuploadstop', e, data);
-
- $('#uploadprogresswrapper input.stop').fadeOut();
- $('#uploadprogressbar').fadeOut();
- Files.updateStorageStatistics();
- });
- fileupload.on('fileuploadfail', function(e, data) {
- OC.Upload.log('progress handle fileuploadfail', e, data);
- //if user pressed cancel hide upload progress bar and cancel button
- if (data.errorThrown === 'abort') {
$('#uploadprogresswrapper input.stop').fadeOut();
$('#uploadprogressbar').fadeOut();
- }
- });
-
- } else {
- console.log('skipping file progress because your browser is broken');
- }
- }
+ Files.updateStorageStatistics();
+ });
+ fileupload.on('fileuploadfail', function(e, data) {
+ OC.Upload.log('progress handle fileuploadfail', e, data);
+ //if user pressed cancel hide upload progress bar and cancel button
+ if (data.errorThrown === 'abort') {
+ $('#uploadprogresswrapper input.stop').fadeOut();
+ $('#uploadprogressbar').fadeOut();
+ }
+ });
- $.assocArraySize = function(obj) {
- // http://stackoverflow.com/a/6700/11236
- var size = 0, key;
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- size++;
+ } else {
+ console.log('skipping file progress because your browser is broken');
}
}
- return size;
- };
- // warn user not to leave the page while upload is in progress
- $(window).on('beforeunload', function(e) {
- if (OC.Upload.isProcessing()) {
- return t('files', 'File upload is in progress. Leaving the page now will cancel the upload.');
- }
- });
+ $.assocArraySize = function(obj) {
+ // http://stackoverflow.com/a/6700/11236
+ var size = 0, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ size++;
+ }
+ }
+ return size;
+ };
- //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
- if (navigator.userAgent.search(/konqueror/i) === -1) {
- $('#file_upload_start').attr('multiple', 'multiple');
- }
+ // warn user not to leave the page while upload is in progress
+ $(window).on('beforeunload', function(e) {
+ if (OC.Upload.isProcessing()) {
+ return t('files', 'File upload is in progress. Leaving the page now will cancel the upload.');
+ }
+ });
- //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder
- var crumb=$('div.crumb').first();
- while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) {
- crumb.children('a').text('...');
- crumb = crumb.next('div.crumb');
- }
- //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent
- var crumb = $('div.crumb').first();
- var next = crumb.next('div.crumb');
- while($('div.controls').height()>40 && next.next('div.crumb').length > 0) {
- crumb.remove();
- crumb = next;
- next = crumb.next('div.crumb');
- }
- //still not enough, start shorting down the current folder name
- var crumb=$('div.crumb>a').last();
- while($('div.controls').height() > 40 && crumb.text().length > 6) {
- var text=crumb.text();
- text = text.substr(0,text.length-6)+'...';
- crumb.text(text);
- }
+ //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
+ if (navigator.userAgent.search(/konqueror/i) === -1) {
+ $('#file_upload_start').attr('multiple', 'multiple');
+ }
- $(document).click(function(ev) {
- // do not close when clicking in the dropdown
- if ($(ev.target).closest('#new').length){
- return;
+ //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder
+ var crumb=$('div.crumb').first();
+ while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) {
+ crumb.children('a').text('...');
+ crumb = crumb.next('div.crumb');
}
- $('#new>ul').hide();
- $('#new').removeClass('active');
- if ($('#new .error').length > 0) {
- $('#new .error').tipsy('hide');
+ //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent
+ var crumb = $('div.crumb').first();
+ var next = crumb.next('div.crumb');
+ while($('div.controls').height()>40 && next.next('div.crumb').length > 0) {
+ crumb.remove();
+ crumb = next;
+ next = crumb.next('div.crumb');
}
- $('#new li').each(function(i,element) {
- if ($(element).children('p').length === 0) {
- $(element).children('form').remove();
- $(element).append('<p>'+$(element).data('text')+'</p>');
- }
- });
- });
- $('#new').click(function(event) {
- event.stopPropagation();
- });
- $('#new>a').click(function() {
- $('#new>ul').toggle();
- $('#new').toggleClass('active');
- });
- $('#new li').click(function() {
- if ($(this).children('p').length === 0) {
- return;
+ //still not enough, start shorting down the current folder name
+ var crumb=$('div.crumb>a').last();
+ while($('div.controls').height() > 40 && crumb.text().length > 6) {
+ var text=crumb.text();
+ text = text.substr(0,text.length-6)+'...';
+ crumb.text(text);
}
-
- $('#new .error').tipsy('hide');
- $('#new li').each(function(i,element) {
- if ($(element).children('p').length === 0) {
- $(element).children('form').remove();
- $(element).append('<p>'+$(element).data('text')+'</p>');
+ $(document).click(function(ev) {
+ // do not close when clicking in the dropdown
+ if ($(ev.target).closest('#new').length){
+ return;
+ }
+ $('#new>ul').hide();
+ $('#new').removeClass('active');
+ if ($('#new .error').length > 0) {
+ $('#new .error').tipsy('hide');
}
+ $('#new li').each(function(i,element) {
+ if ($(element).children('p').length === 0) {
+ $(element).children('form').remove();
+ $(element).append('<p>'+$(element).data('text')+'</p>');
+ }
+ });
});
-
- var type=$(this).data('type');
- var text=$(this).children('p').text();
- $(this).data('text',text);
- $(this).children('p').remove();
-
- // add input field
- var form = $('<form></form>');
- var input = $('<input type="text">');
- var newName = $(this).attr('data-newname') || '';
- if (newName) {
- input.val(newName);
- }
- form.append(input);
- $(this).append(form);
- var lastPos;
- var checkInput = function () {
- var filename = input.val();
- if (type === 'web' && filename.length === 0) {
- throw t('files', 'URL cannot be empty');
- } else if (type !== 'web' && !Files.isFileNameValid(filename)) {
- // Files.isFileNameValid(filename) throws an exception itself
- } else if ($('#dir').val() === '/' && filename === 'Shared') {
- throw t('files', 'In the home folder \'Shared\' is a reserved filename');
- } else if (FileList.inList(filename)) {
- throw t('files', '{new_name} already exists', {new_name: filename});
- } else {
- return true;
+ $('#new').click(function(event) {
+ event.stopPropagation();
+ });
+ $('#new>a').click(function() {
+ $('#new>ul').toggle();
+ $('#new').toggleClass('active');
+ });
+ $('#new li').click(function() {
+ if ($(this).children('p').length === 0) {
+ return;
}
- };
- // verify filename on typing
- input.keyup(function(event) {
- try {
- checkInput();
- input.tipsy('hide');
- input.removeClass('error');
- } catch (error) {
- input.attr('title', error);
- input.tipsy({gravity: 'w', trigger: 'manual'});
- input.tipsy('show');
- input.addClass('error');
- }
- });
+ $('#new .error').tipsy('hide');
- input.focus();
- // pre select name up to the extension
- lastPos = newName.lastIndexOf('.');
- if (lastPos === -1) {
- lastPos = newName.length;
- }
- input.selectRange(0, lastPos);
- form.submit(function(event) {
- event.stopPropagation();
- event.preventDefault();
- try {
- checkInput();
- var newname = input.val();
- if (FileList.lastAction) {
- FileList.lastAction();
+ $('#new li').each(function(i,element) {
+ if ($(element).children('p').length === 0) {
+ $(element).children('form').remove();
+ $(element).append('<p>'+$(element).data('text')+'</p>');
}
- var name = getUniqueName(newname);
- if (newname !== name) {
- FileList.checkName(name, newname, true);
- var hidden = true;
+ });
+
+ var type=$(this).data('type');
+ var text=$(this).children('p').text();
+ $(this).data('text',text);
+ $(this).children('p').remove();
+
+ // add input field
+ var form = $('<form></form>');
+ var input = $('<input type="text">');
+ var newName = $(this).attr('data-newname') || '';
+ if (newName) {
+ input.val(newName);
+ }
+ form.append(input);
+ $(this).append(form);
+ var lastPos;
+ var checkInput = function () {
+ var filename = input.val();
+ if (type === 'web' && filename.length === 0) {
+ throw t('files', 'URL cannot be empty');
+ } else if (type !== 'web' && !Files.isFileNameValid(filename)) {
+ // Files.isFileNameValid(filename) throws an exception itself
+ } else if (FileList.getCurrentDirectory() === '/' && filename.toLowerCase() === 'shared') {
+ throw t('files', 'In the home folder \'Shared\' is a reserved filename');
+ } else if (FileList.inList(filename)) {
+ throw t('files', '{new_name} already exists', {new_name: filename});
} else {
- var hidden = false;
+ return true;
+ }
+ };
+
+ // verify filename on typing
+ input.keyup(function(event) {
+ try {
+ checkInput();
+ input.tipsy('hide');
+ input.removeClass('error');
+ } catch (error) {
+ input.attr('title', error);
+ input.tipsy({gravity: 'w', trigger: 'manual'});
+ input.tipsy('show');
+ input.addClass('error');
}
- switch(type) {
- case 'file':
- $.post(
- OC.filePath('files', 'ajax', 'newfile.php'),
- {dir:$('#dir').val(), filename:name},
- function(result) {
- if (result.status === 'success') {
- var date = new Date();
- // TODO: ideally addFile should be able to receive
- // all attributes and set them automatically,
- // and also auto-load the preview
- var tr = FileList.addFile(name, 0, date, false, hidden);
- tr.attr('data-size', result.data.size);
- tr.attr('data-mime', result.data.mime);
- tr.attr('data-id', result.data.id);
- tr.attr('data-etag', result.data.etag);
- tr.find('.filesize').text(humanFileSize(result.data.size));
- var path = getPathForPreview(name);
- Files.lazyLoadPreview(path, result.data.mime, function(previewpath) {
- tr.find('td.filename').attr('style','background-image:url('+previewpath+')');
- }, null, null, result.data.etag);
- FileActions.display(tr.find('td.filename'), true);
- } else {
- OC.dialogs.alert(result.data.message, t('core', 'Could not create file'));
+ });
+
+ input.focus();
+ // pre select name up to the extension
+ lastPos = newName.lastIndexOf('.');
+ if (lastPos === -1) {
+ lastPos = newName.length;
+ }
+ input.selectRange(0, lastPos);
+ form.submit(function(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ try {
+ checkInput();
+ var newname = input.val();
+ if (FileList.lastAction) {
+ FileList.lastAction();
+ }
+ var name = getUniqueName(newname);
+ if (newname !== name) {
+ FileList.checkName(name, newname, true);
+ var hidden = true;
+ } else {
+ var hidden = false;
+ }
+ switch(type) {
+ case 'file':
+ $.post(
+ OC.filePath('files', 'ajax', 'newfile.php'),
+ {dir:$('#dir').val(), filename:name},
+ function(result) {
+ if (result.status === 'success') {
+ var date = new Date();
+ // TODO: ideally addFile should be able to receive
+ // all attributes and set them automatically,
+ // and also auto-load the preview
+ var tr = FileList.addFile(name, 0, date, false, hidden);
+ tr.attr('data-size', result.data.size);
+ tr.attr('data-mime', result.data.mime);
+ tr.attr('data-id', result.data.id);
+ tr.attr('data-etag', result.data.etag);
+ tr.find('.filesize').text(humanFileSize(result.data.size));
+ var path = getPathForPreview(name);
+ Files.lazyLoadPreview(path, result.data.mime, function(previewpath) {
+ tr.find('td.filename').attr('style','background-image:url('+previewpath+')');
+ }, null, null, result.data.etag);
+ FileActions.display(tr.find('td.filename'), true);
+ } else {
+ OC.dialogs.alert(result.data.message, t('core', 'Could not create file'));
+ }
}
- }
- );
- break;
- case 'folder':
- $.post(
- OC.filePath('files','ajax','newfolder.php'),
- {dir:$('#dir').val(), foldername:name},
- function(result) {
- if (result.status === 'success') {
- var date=new Date();
- FileList.addDir(name, 0, date, hidden);
- var tr = FileList.findFileEl(name);
- tr.attr('data-id', result.data.id);
- } else {
- OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
+ );
+ break;
+ case 'folder':
+ $.post(
+ OC.filePath('files','ajax','newfolder.php'),
+ {dir:$('#dir').val(), foldername:name},
+ function(result) {
+ if (result.status === 'success') {
+ var date=new Date();
+ FileList.addDir(name, 0, date, hidden);
+ var tr = FileList.findFileEl(name);
+ tr.attr('data-id', result.data.id);
+ } else {
+ OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
+ }
}
+ );
+ break;
+ case 'web':
+ if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') {
+ name = 'http://' + name;
}
- );
- break;
- case 'web':
- if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') {
- name = 'http://' + name;
- }
- var localName=name;
- if (localName.substr(localName.length-1,1)==='/') {//strip /
- localName=localName.substr(0,localName.length-1);
- }
- if (localName.indexOf('/')) {//use last part of url
- localName=localName.split('/').pop();
- } else { //or the domain
- localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.','');
- }
- localName = getUniqueName(localName);
- //IE < 10 does not fire the necessary events for the progress bar.
- if ($('html.lte9').length === 0) {
- $('#uploadprogressbar').progressbar({value:0});
- $('#uploadprogressbar').fadeIn();
- }
-
- var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
- eventSource.listen('progress',function(progress) {
+ var localName=name;
+ if (localName.substr(localName.length-1,1)==='/') {//strip /
+ localName=localName.substr(0,localName.length-1);
+ }
+ if (localName.indexOf('/')) {//use last part of url
+ localName=localName.split('/').pop();
+ } else { //or the domain
+ localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.','');
+ }
+ localName = getUniqueName(localName);
//IE < 10 does not fire the necessary events for the progress bar.
if ($('html.lte9').length === 0) {
- $('#uploadprogressbar').progressbar('value',progress);
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
}
- });
- eventSource.listen('success',function(data) {
- var mime = data.mime;
- var size = data.size;
- var id = data.id;
- $('#uploadprogressbar').fadeOut();
- var date = new Date();
- FileList.addFile(localName, size, date, false, hidden);
- var tr = FileList.findFileEl(localName);
- tr.data('mime', mime).data('id', id);
- tr.attr('data-id', id);
- var path = $('#dir').val()+'/'+localName;
- Files.lazyLoadPreview(path, mime, function(previewpath) {
- tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')');
- }, null, null, data.etag);
- FileActions.display(tr.find('td.filename'), true);
- });
- eventSource.listen('error',function(error) {
- $('#uploadprogressbar').fadeOut();
- var message = (error && error.message) || t('core', 'Error fetching URL');
- OC.Notification.show(message);
- //hide notification after 10 sec
- setTimeout(function() {
- OC.Notification.hide();
- }, 10000);
- });
- break;
+
+ var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
+ eventSource.listen('progress',function(progress) {
+ //IE < 10 does not fire the necessary events for the progress bar.
+ if ($('html.lte9').length === 0) {
+ $('#uploadprogressbar').progressbar('value',progress);
+ }
+ });
+ eventSource.listen('success',function(data) {
+ var mime = data.mime;
+ var size = data.size;
+ var id = data.id;
+ $('#uploadprogressbar').fadeOut();
+ var date = new Date();
+ FileList.addFile(localName, size, date, false, hidden);
+ var tr = FileList.findFileEl(localName);
+ tr.data('mime', mime).data('id', id);
+ tr.attr('data-id', id);
+ var path = $('#dir').val()+'/'+localName;
+ Files.lazyLoadPreview(path, mime, function(previewpath) {
+ tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')');
+ }, null, null, data.etag);
+ FileActions.display(tr.find('td.filename'), true);
+ });
+ eventSource.listen('error',function(error) {
+ $('#uploadprogressbar').fadeOut();
+ var message = (error && error.message) || t('core', 'Error fetching URL');
+ OC.Notification.show(message);
+ //hide notification after 10 sec
+ setTimeout(function() {
+ OC.Notification.hide();
+ }, 10000);
+ });
+ break;
+ }
+ var li=form.parent();
+ form.remove();
+ /* workaround for IE 9&10 click event trap, 2 lines: */
+ $('input').first().focus();
+ $('#content').focus();
+ li.append('<p>'+li.data('text')+'</p>');
+ $('#new>a').click();
+ } catch (error) {
+ input.attr('title', error);
+ input.tipsy({gravity: 'w', trigger: 'manual'});
+ input.tipsy('show');
+ input.addClass('error');
}
- var li=form.parent();
- form.remove();
- /* workaround for IE 9&10 click event trap, 2 lines: */
- $('input').first().focus();
- $('#content').focus();
- li.append('<p>'+li.data('text')+'</p>');
- $('#new>a').click();
- } catch (error) {
- input.attr('title', error);
- input.tipsy({gravity: 'w', trigger: 'manual'});
- input.tipsy('show');
- input.addClass('error');
- }
+ });
});
- });
- window.file_upload_param = file_upload_param;
+ window.file_upload_param = file_upload_param;
+ return file_upload_param;
+ }
+};
+
+$(document).ready(function() {
+ OC.Upload.init();
});
+
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 550c10dba3e..503bf681139 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -137,7 +137,9 @@ window.FileList={
var download_url = null;
if (!param.download_url) {
- download_url = OC.Router.generate('download', { file: $('#dir').val()+'/'+name });
+ download_url = OC.generateUrl(
+ 'apps/files/download{file}',
+ { file: $('#dir').val()+'/'+name });
} else {
download_url = param.download_url;
}
@@ -419,15 +421,12 @@ window.FileList={
len = input.val().length;
}
input.selectRange(0, len);
-
var checkInput = function () {
var filename = input.val();
if (filename !== oldname) {
- if (!Files.isFileNameValid(filename)) {
- // Files.isFileNameValid(filename) throws an exception itself
- } else if($('#dir').val() === '/' && filename === 'Shared') {
- throw t('files','In the home folder \'Shared\' is a reserved filename');
- } else if (FileList.inList(filename)) {
+ // Files.isFileNameValid(filename) throws an exception itself
+ Files.isFileNameValid(filename, FileList.getCurrentDirectory());
+ if (FileList.inList(filename)) {
throw t('files', '{new_name} already exists', {new_name: filename});
}
}
@@ -1156,9 +1155,9 @@ $(document).ready(function() {
// need to initially switch the dir to the one from the hash (IE8)
FileList.changeDirectory(parseCurrentDirFromUrl(), false, true);
}
- }
- FileList.setCurrentDir(parseCurrentDirFromUrl(), false);
+ FileList.setCurrentDir(parseCurrentDirFromUrl(), false);
+ }
FileList.createFileSummary();
});
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index f4546120702..1186a72a44f 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -87,9 +87,12 @@ var Files = {
* Throws a string exception with an error message if
* the file name is not valid
*/
- isFileNameValid: function (name) {
+ isFileNameValid: function (name, root) {
var trimmedName = name.trim();
- if (trimmedName === '.' || trimmedName === '..') {
+ if (trimmedName === '.'
+ || trimmedName === '..'
+ || (root === '/' && trimmedName.toLowerCase() === 'shared'))
+ {
throw t('files', '"{name}" is an invalid file name.', {name: name});
} else if (trimmedName.length === 0) {
throw t('files', 'File name cannot be empty.');
@@ -780,9 +783,9 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
if ( $('#isPublic').length ) {
urlSpec.t = $('#dirToken').val();
- previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
+ previewURL = OC.generateUrl('/publicpreview.png?') + $.param(urlSpec);
} else {
- previewURL = OC.Router.generate('core_ajax_preview', urlSpec);
+ previewURL = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
}
previewURL = previewURL.replace('(', '%28');
previewURL = previewURL.replace(')', '%29');
diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php
index f4fb96a7a7c..8a7a1e370eb 100644
--- a/apps/files/templates/part.list.php
+++ b/apps/files/templates/part.list.php
@@ -17,7 +17,13 @@ $totalsize = 0; ?>
data-mime="<?php p($file['mimetype'])?>"
data-size="<?php p($file['size']);?>"
data-etag="<?php p($file['etag']);?>"
- data-permissions="<?php p($file['permissions']); ?>">
+ data-permissions="<?php p($file['permissions']); ?>"
+
+ <?php if(isset($file['displayname_owner'])): ?>
+ data-share-owner="<?php p($file['displayname_owner']) ?>"
+ <?php endif; ?>
+ >
+
<?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?>
<td class="filename svg preview-icon"
<?php else: ?>
@@ -34,17 +40,15 @@ $totalsize = 0; ?>
<span class="nametext">
<?php print_unescaped(htmlspecialchars($file['name']));?>
</span>
+ <span class="uploadtext" currentUploads="0">
+ </span>
+ </a>
<?php else: ?>
<a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>">
<label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label>
<span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span>
</a>
<?php endif; ?>
- <?php if($file['type'] == 'dir'):?>
- <span class="uploadtext" currentUploads="0">
- </span>
- <?php endif;?>
- </a>
</td>
<td class="filesize"
style="color:rgb(<?php p($simple_size_color.','.$simple_size_color.','.$simple_size_color) ?>)">
diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js
new file mode 100644
index 00000000000..2b4341ef1c3
--- /dev/null
+++ b/apps/files/tests/js/fileUploadSpec.js
@@ -0,0 +1,127 @@
+/**
+* ownCloud
+*
+* @author Vincent Petry
+* @copyright 2014 Vincent Petry <pvince81@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/>.
+*
+*/
+
+/* global OC */
+describe('OC.Upload tests', function() {
+ var $dummyUploader;
+ var testFile;
+
+ beforeEach(function() {
+ testFile = {
+ name: 'test.txt',
+ size: 5000, // 5 KB
+ type: 'text/plain',
+ lastModifiedDate: new Date()
+ };
+ // need a dummy button because file-upload checks on it
+ $('#testArea').append(
+ '<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' +
+ '<input type="hidden" id="upload_limit" name="upload_limit" value="10000000">' + // 10 MB
+ '<input type="hidden" id="free_space" name="free_space" value="50000000">' // 50 MB
+ );
+ $dummyUploader = $('#file_upload_start');
+ });
+ afterEach(function() {
+ delete window.file_upload_param;
+ $dummyUploader = undefined;
+ });
+ describe('Adding files for upload', function() {
+ var params;
+ var failStub;
+
+ beforeEach(function() {
+ params = OC.Upload.init();
+ failStub = sinon.stub();
+ $dummyUploader.on('fileuploadfail', failStub);
+ });
+ afterEach(function() {
+ params = undefined;
+ failStub = undefined;
+ });
+
+ /**
+ * Add file for upload
+ * @param file file data
+ */
+ function addFile(file) {
+ return params.add.call(
+ $dummyUploader[0],
+ {},
+ {
+ originalFiles: {},
+ files: [file]
+ });
+ }
+
+ it('adds file when size is below limits', function() {
+ var result = addFile(testFile);
+ expect(result).toEqual(true);
+ });
+ it('adds file when free space is unknown', function() {
+ var result;
+ $('#free_space').val(-2);
+
+ result = addFile(testFile);
+
+ expect(result).toEqual(true);
+ expect(failStub.notCalled).toEqual(true);
+ });
+ it('does not add file if it exceeds upload limit', function() {
+ var result;
+ $('#upload_limit').val(1000);
+
+ result = addFile(testFile);
+
+ expect(result).toEqual(false);
+ expect(failStub.calledOnce).toEqual(true);
+ expect(failStub.getCall(0).args[1].textStatus).toEqual('sizeexceedlimit');
+ expect(failStub.getCall(0).args[1].errorThrown).toEqual(
+ 'Total file size 5 kB exceeds upload limit 1000 B'
+ );
+ });
+ it('does not add file if it exceeds free space', function() {
+ var result;
+ $('#free_space').val(1000);
+
+ result = addFile(testFile);
+
+ expect(result).toEqual(false);
+ expect(failStub.calledOnce).toEqual(true);
+ expect(failStub.getCall(0).args[1].textStatus).toEqual('notenoughspace');
+ expect(failStub.getCall(0).args[1].errorThrown).toEqual(
+ 'Not enough free space, you are uploading 5 kB but only 1000 B is left'
+ );
+ });
+ it('does not add file if it has invalid characters', function() {
+ var result;
+ testFile.name = 'stars*stars.txt';
+
+ result = addFile(testFile);
+
+ expect(result).toEqual(false);
+ expect(failStub.calledOnce).toEqual(true);
+ expect(failStub.getCall(0).args[1].textStatus).toEqual('invalidcharacters');
+ expect(failStub.getCall(0).args[1].errorThrown.substr(0, 12)).toEqual(
+ 'Invalid name'
+ );
+ });
+ });
+});
diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js
index 018c8ef0f3c..95bf87e03ec 100644
--- a/apps/files/tests/js/filesSpec.js
+++ b/apps/files/tests/js/filesSpec.js
@@ -48,6 +48,41 @@ describe('Files tests', function() {
expect(error).toEqual(false);
}
});
+ it('Validates correct file names do not create Shared folder in root', function() {
+ // create shared file in subfolder
+ var error = false;
+ try {
+ expect(Files.isFileNameValid('shared', '/foo')).toEqual(true);
+ expect(Files.isFileNameValid('Shared', '/foo')).toEqual(true);
+ }
+ catch (e) {
+ error = e;
+ }
+ expect(error).toEqual(false);
+
+ // create shared file in root
+ var threwException = false;
+ try {
+ Files.isFileNameValid('Shared', '/');
+ console.error('Invalid file name not detected');
+ }
+ catch (e) {
+ threwException = true;
+ }
+ expect(threwException).toEqual(true);
+
+ // create shared file in root
+ var threwException = false;
+ try {
+ Files.isFileNameValid('shared', '/');
+ console.error('Invalid file name not detected');
+ }
+ catch (e) {
+ threwException = true;
+ }
+ expect(threwException).toEqual(true);
+
+ });
it('Detects invalid file names', function() {
var fileNames = [
'',
diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js
index c2140a6f1eb..785d02002fa 100644
--- a/apps/files_encryption/js/settings-admin.js
+++ b/apps/files_encryption/js/settings-admin.js
@@ -7,28 +7,6 @@
* See the COPYING-README file.
*/
-OC.msg={
- startSaving:function(selector){
- $(selector)
- .html( t('settings', 'Saving...') )
- .removeClass('success')
- .removeClass('error')
- .stop(true, true)
- .show();
- },
- finishedSaving:function(selector, data){
- if( data.status === "success" ){
- $(selector).html( data.data.message )
- .addClass('success')
- .stop(true, true)
- .delay(3000)
- .fadeOut(900);
- }else{
- $(selector).html( data.data.message ).addClass('error');
- }
- }
-};
-
$(document).ready(function(){
// Trigger ajax on recoveryAdmin status change
var enabledStatus = $('#adminEnableRecovery').val();
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index 9d456f6c517..b7e1599c1fe 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -38,6 +38,7 @@ class Proxy extends \OC_FileProxy {
private static $blackList = null; //mimetypes blacklisted from encryption
private static $unencryptedSizes = array(); // remember unencrypted size
+ private static $fopenMode = array(); // remember the fopen mode
/**
* Check if a file requires encryption
@@ -146,7 +147,7 @@ class Proxy extends \OC_FileProxy {
if ( isset(self::$unencryptedSizes[$normalizedPath]) ) {
$view = new \OC_FilesystemView('/');
$view->putFileInfo($normalizedPath,
- array('encrypted' => true, 'encrypted_size' => self::$unencryptedSizes[$normalizedPath]));
+ array('encrypted' => true, 'unencrypted_size' => self::$unencryptedSizes[$normalizedPath]));
unset(self::$unencryptedSizes[$normalizedPath]);
}
@@ -214,6 +215,16 @@ class Proxy extends \OC_FileProxy {
}
/**
+ * @brief remember initial fopen mode because sometimes it gets changed during the request
+ * @param string $path path
+ * @param string $mode type of access
+ */
+ public function preFopen($path, $mode) {
+ self::$fopenMode[$path] = $mode;
+ }
+
+
+ /**
* @param $path
* @param $result
* @return resource
@@ -240,7 +251,15 @@ class Proxy extends \OC_FileProxy {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- $meta = stream_get_meta_data($result);
+ // if we remember the mode from the pre proxy we re-use it
+ // oterwise we fall back to stream_get_meta_data()
+ if (isset(self::$fopenMode[$path])) {
+ $mode = self::$fopenMode[$path];
+ unset(self::$fopenMode[$path]);
+ } else {
+ $meta = stream_get_meta_data($result);
+ $mode = $meta['mode'];
+ }
$view = new \OC_FilesystemView('');
@@ -258,14 +277,15 @@ class Proxy extends \OC_FileProxy {
// Open the file using the crypto stream wrapper
// protocol and let it do the decryption work instead
- $result = fopen('crypt://' . $path, $meta['mode']);
+ $result = fopen('crypt://' . $path, $mode);
} elseif (
- self::shouldEncrypt($path)
- and $meta['mode'] !== 'r'
- and $meta['mode'] !== 'rb'
+ self::shouldEncrypt($path)
+ and $mode !== 'r'
+ and $mode !== 'rb'
+
) {
- $result = fopen('crypt://' . $path, $meta['mode']);
+ $result = fopen('crypt://' . $path, $mode);
}
// Re-enable the proxy
@@ -320,6 +340,13 @@ class Proxy extends \OC_FileProxy {
// if path is a folder do nothing
if ($view->is_dir($path)) {
+ $proxyState = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+ $fileInfo = $view->getFileInfo($path);
+ \OC_FileProxy::$enabled = $proxyState;
+ if ($fileInfo['unencrypted_size'] > 0) {
+ return $fileInfo['unencrypted_size'];
+ }
return $size;
}
diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php
index aa58e33e9d2..3daaa06425f 100644
--- a/apps/files_encryption/lib/session.php
+++ b/apps/files_encryption/lib/session.php
@@ -134,6 +134,14 @@ class Session {
}
+ /**
+ * @brief remove encryption keys and init status from session
+ */
+ public function closeSession() {
+ \OC::$session->remove('encryptionInitialized');
+ \OC::$session->remove('privateKey');
+ }
+
/**
* @brief Gets status if we already tried to initialize the encryption app
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 88eacc6f136..58ac03373a7 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -167,6 +167,9 @@ class Stream {
} else {
$this->meta = stream_get_meta_data($this->handle);
+ // sometimes fopen changes the mode, e.g. for a url "r" convert to "r+"
+ // but we need to remember the original access type
+ $this->meta['mode'] = $mode;
}
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index ec06bd52f5e..3db5a423478 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -135,7 +135,6 @@ class Util {
// Set directories to check / create
$setUpDirs = array(
$this->userDir,
- $this->userFilesDir,
$this->publicKeyDir,
$this->encryptionDir,
$this->keyfilesPath,
@@ -1772,4 +1771,12 @@ class Util {
return $session;
}
+ /*
+ * @brief remove encryption related keys from the session
+ */
+ public function closeEncryptionSession() {
+ $session = new \OCA\Encryption\Session($this->view);
+ $session->closeSession();
+ }
+
}
diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php
index 51cc0b795e3..647ee955eb1 100644
--- a/apps/files_encryption/tests/proxy.php
+++ b/apps/files_encryption/tests/proxy.php
@@ -112,4 +112,24 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
}
+ function testPostFileSizeWithDirectory() {
+
+ $this->view->file_put_contents($this->filename, $this->data);
+
+ \OC_FileProxy::$enabled = false;
+
+ // get root size, must match the file's unencrypted size
+ $unencryptedSize = $this->view->filesize('');
+
+ \OC_FileProxy::$enabled = true;
+
+ $encryptedSize = $this->view->filesize('');
+
+ $this->assertTrue($encryptedSize !== $unencryptedSize);
+
+ // cleanup
+ $this->view->unlink($this->filename);
+
+ }
+
}
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php
index f70e30c4d73..203ba55dbfd 100755
--- a/apps/files_encryption/tests/util.php
+++ b/apps/files_encryption/tests/util.php
@@ -344,7 +344,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
// check if mtime and etags unchanged
$this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']);
- $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
+ $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
$this->view->unlink($this->userId . '/files/' . $filename);
}
@@ -373,7 +373,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
// check if mtime and etags unchanged
$this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']);
- $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
+ $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
// file should no longer be encrypted
$this->assertEquals(0, $fileInfoUnencrypted['encrypted']);
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index 895f97bd2c3..cd2a3103eb7 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -264,7 +264,7 @@ $(document).ready(function() {
OC.MountConfig.saveStorage($(this).parent().parent());
});
- $('#sslCertificate').on('click', 'td.remove>img', function() {
+ $('#sslCertificate').on('click', 'td.remove>img', function() {
var $tr = $(this).parent().parent();
var row = this.parentNode.parentNode;
$.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id});
@@ -302,13 +302,23 @@ $(document).ready(function() {
});
$('#allowUserMounting').bind('change', function() {
+ OC.msg.startSaving('#userMountingMsg');
if (this.checked) {
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');
+ $('#userMountingBackups').removeClass('hidden');
} else {
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');
+ $('#userMountingBackups').addClass('hidden');
}
+ OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});
});
+ $('input[name="allowUserMountingBackends\\[\\]"]').bind('change', function() {
+ OC.msg.startSaving('#userMountingMsg');
+ var user_mounting_backends = $('input[name="allowUserMountingBackends\\[\\]"]:checked').map(function(){return $(this).val();}).get();
+ OC.AppConfig.setValue('files_external', 'user_mounting_backends', user_mounting_backends.join());
+ OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});
+ });
});
})();
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index 9a8b95c14c9..2767076eefa 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -45,7 +45,7 @@ class OC_Mount_Config {
'datadir' => 'Location'));
$backends['\OC\Files\Storage\AmazonS3']=array(
- 'backend' => 'Amazon S3',
+ 'backend' => 'Amazon S3 and compliant',
'configuration' => array(
'key' => 'Access Key',
'secret' => '*Secret Key',
@@ -156,6 +156,35 @@ class OC_Mount_Config {
}
/**
+ * Get details on each of the external storage backends, used for the mount config UI
+ * Some backends are not available as a personal backend, f.e. Local and such that have
+ * been disabled by the admin.
+ *
+ * If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
+ * If the configuration parameter should be secret, add a '*' to the beginning of the value
+ * If the configuration parameter is a boolean, add a '!' to the beginning of the value
+ * If the configuration parameter is optional, add a '&' to the beginning of the value
+ * If the configuration parameter is hidden, add a '#' to the beginning of the value
+ * @return array
+ */
+ public static function getPersonalBackends() {
+
+ $backends = self::getBackends();
+
+ // Remove local storage and other disabled storages
+ unset($backends['\OC\Files\Storage\Local']);
+
+ $allowed_backends = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
+ foreach ($backends as $backend => $null) {
+ if (!in_array($backend, $allowed_backends)) {
+ unset($backends[$backend]);
+ }
+ }
+
+ return $backends;
+ }
+
+ /**
* Get the system mount points
* The returned array is not in the same format as getUserMountPoints()
* @return array
@@ -287,11 +316,12 @@ class OC_Mount_Config {
if (!isset($backends[$class])) {
// invalid backend
return false;
- }
+ }
if ($isPersonal) {
// Verify that the mount point applies for the current user
- // Prevent non-admin users from mounting local storage
- if ($applicable !== OCP\User::getUser() || strtolower($class) === '\oc\files\storage\local') {
+ // Prevent non-admin users from mounting local storage and other disabled backends
+ $allowed_backends = self::getPersonalBackends();
+ if ($applicable != OCP\User::getUser() || !in_array($class, $allowed_backends)) {
return false;
}
$mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
@@ -359,7 +389,8 @@ class OC_Mount_Config {
$jsonFile = OC_User::getHome(OCP\User::getUser()).'/mount.json';
} else {
$phpFile = OC::$SERVERROOT.'/config/mount.php';
- $jsonFile = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
+ $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/');
+ $jsonFile = \OC_Config::getValue('mount_file', $datadir . '/mount.json');
}
if (is_file($jsonFile)) {
$mountPoints = json_decode(file_get_contents($jsonFile), true);
@@ -385,7 +416,8 @@ class OC_Mount_Config {
if ($isPersonal) {
$file = OC_User::getHome(OCP\User::getUser()).'/mount.json';
} else {
- $file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
+ $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/');
+ $file = \OC_Config::getValue('mount_file', $datadir . '/mount.json');
}
$content = json_encode($data);
@file_put_contents($file, $content);
@@ -444,7 +476,7 @@ class OC_Mount_Config {
*/
public static function checksmbclient() {
if(function_exists('shell_exec')) {
- $output=shell_exec('which smbclient 2> /dev/null');
+ $output=shell_exec('command -v smbclient 2> /dev/null');
return !empty($output);
}else{
return false;
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
index 9afe73aebd7..279ae716935 100644
--- a/apps/files_external/lib/webdav.php
+++ b/apps/files_external/lib/webdav.php
@@ -8,7 +8,7 @@
namespace OC\Files\Storage;
-class DAV extends \OC\Files\Storage\Common{
+class DAV extends \OC\Files\Storage\Common {
private $password;
private $user;
private $host;
@@ -21,7 +21,7 @@ class DAV extends \OC\Files\Storage\Common{
*/
private $client;
- private static $tempFiles=array();
+ private static $tempFiles = array();
public function __construct($params) {
if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
@@ -29,9 +29,9 @@ class DAV extends \OC\Files\Storage\Common{
//remove leading http[s], will be generated in createBaseUri()
if (substr($host, 0, 8) == "https://") $host = substr($host, 8);
else if (substr($host, 0, 7) == "http://") $host = substr($host, 7);
- $this->host=$host;
- $this->user=$params['user'];
- $this->password=$params['password'];
+ $this->host = $host;
+ $this->user = $params['user'];
+ $this->password = $params['password'];
if (isset($params['secure'])) {
if (is_string($params['secure'])) {
$this->secure = ($params['secure'] === 'true');
@@ -42,25 +42,25 @@ class DAV extends \OC\Files\Storage\Common{
$this->secure = false;
}
if ($this->secure === true) {
- $certPath=\OC_User::getHome(\OC_User::getUser()) . '/files_external/rootcerts.crt';
+ $certPath = \OC_User::getHome(\OC_User::getUser()) . '/files_external/rootcerts.crt';
if (file_exists($certPath)) {
- $this->certPath=$certPath;
+ $this->certPath = $certPath;
}
}
- $this->root=isset($params['root'])?$params['root']:'/';
- if ( ! $this->root || $this->root[0]!='/') {
- $this->root='/'.$this->root;
+ $this->root = isset($params['root']) ? $params['root'] : '/';
+ if (!$this->root || $this->root[0] != '/') {
+ $this->root = '/' . $this->root;
}
- if (substr($this->root, -1, 1)!='/') {
- $this->root.='/';
+ if (substr($this->root, -1, 1) != '/') {
+ $this->root .= '/';
}
} else {
throw new \Exception();
}
}
- private function init(){
- if($this->ready) {
+ private function init() {
+ if ($this->ready) {
return;
}
$this->ready = true;
@@ -78,28 +78,28 @@ class DAV extends \OC\Files\Storage\Common{
}
}
- public function getId(){
+ public function getId() {
return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root;
}
protected function createBaseUri() {
- $baseUri='http';
+ $baseUri = 'http';
if ($this->secure) {
- $baseUri.='s';
+ $baseUri .= 's';
}
- $baseUri.='://'.$this->host.$this->root;
+ $baseUri .= '://' . $this->host . $this->root;
return $baseUri;
}
public function mkdir($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
return $this->simpleResponse('MKCOL', $path, null, 201);
}
public function rmdir($path) {
$this->init();
- $path=$this->cleanPath($path) . '/';
+ $path = $this->cleanPath($path) . '/';
// FIXME: some WebDAV impl return 403 when trying to DELETE
// a non-empty folder
return $this->simpleResponse('DELETE', $path, null, 204);
@@ -107,35 +107,35 @@ class DAV extends \OC\Files\Storage\Common{
public function opendir($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
- $response=$this->client->propfind($this->encodePath($path), array(), 1);
- $id=md5('webdav'.$this->root.$path);
+ $response = $this->client->propfind($this->encodePath($path), array(), 1);
+ $id = md5('webdav' . $this->root . $path);
$content = array();
- $files=array_keys($response);
- array_shift($files);//the first entry is the current directory
+ $files = array_keys($response);
+ array_shift($files); //the first entry is the current directory
foreach ($files as $file) {
$file = urldecode(basename($file));
- $content[]=$file;
+ $content[] = $file;
}
\OC\Files\Stream\Dir::register($id, $content);
- return opendir('fakedir://'.$id);
- } catch(\Exception $e) {
+ return opendir('fakedir://' . $id);
+ } catch (\Exception $e) {
return false;
}
}
public function filetype($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
- $response=$this->client->propfind($this->encodePath($path), array('{DAV:}resourcetype'));
+ $response = $this->client->propfind($this->encodePath($path), array('{DAV:}resourcetype'));
$responseType = array();
if (isset($response["{DAV:}resourcetype"])) {
- $responseType=$response["{DAV:}resourcetype"]->resourceType;
+ $responseType = $response["{DAV:}resourcetype"]->resourceType;
}
- return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
- } catch(\Exception $e) {
+ return (count($responseType) > 0 and $responseType[0] == "{DAV:}collection") ? 'dir' : 'file';
+ } catch (\Exception $e) {
error_log($e->getMessage());
\OCP\Util::writeLog("webdav client", \OCP\Util::sanitizeHTML($e->getMessage()), \OCP\Util::ERROR);
return false;
@@ -144,11 +144,11 @@ class DAV extends \OC\Files\Storage\Common{
public function file_exists($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
$this->client->propfind($this->encodePath($path), array('{DAV:}resourcetype'));
- return true;//no 404 exception
- } catch(\Exception $e) {
+ return true; //no 404 exception
+ } catch (\Exception $e) {
return false;
}
}
@@ -160,34 +160,34 @@ class DAV extends \OC\Files\Storage\Common{
public function fopen($path, $mode) {
$this->init();
- $path=$this->cleanPath($path);
- switch($mode) {
+ $path = $this->cleanPath($path);
+ switch ($mode) {
case 'r':
case 'rb':
- if ( ! $this->file_exists($path)) {
+ if (!$this->file_exists($path)) {
return false;
}
//straight up curl instead of sabredav here, sabredav put's the entire get result in memory
$curl = curl_init();
$fp = fopen('php://temp', 'r+');
- curl_setopt($curl, CURLOPT_USERPWD, $this->user.':'.$this->password);
- curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$this->encodePath($path));
+ curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password);
+ curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($path));
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
if ($this->secure === true) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
- if($this->certPath){
+ if ($this->certPath) {
curl_setopt($curl, CURLOPT_CAINFO, $this->certPath);
}
}
-
- curl_exec ($curl);
+
+ curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode !== 200) {
\OCP\Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, \OCP\Util::ERROR);
}
- curl_close ($curl);
+ curl_close($curl);
rewind($fp);
return $fp;
case 'w':
@@ -203,18 +203,19 @@ class DAV extends \OC\Files\Storage\Common{
case 'c':
case 'c+':
//emulate these
- if (strrpos($path, '.')!==false) {
- $ext=substr($path, strrpos($path, '.'));
+ if (strrpos($path, '.') !== false) {
+ $ext = substr($path, strrpos($path, '.'));
} else {
- $ext='';
+ $ext = '';
}
- $tmpFile = \OCP\Files::tmpFile($ext);
- \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
- if($this->file_exists($path)) {
- $this->getFile($path, $tmpFile);
+ if ($this->file_exists($path)) {
+ $tmpFile = $this->getCachedFile($path);
+ } else {
+ $tmpFile = \OCP\Files::tmpFile($ext);
}
- self::$tempFiles[$tmpFile]=$path;
- return fopen('close://'.$tmpFile, $mode);
+ \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
+ self::$tempFiles[$tmpFile] = $path;
+ return fopen('close://' . $tmpFile, $mode);
}
}
@@ -227,32 +228,31 @@ class DAV extends \OC\Files\Storage\Common{
public function free_space($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
- $response=$this->client->propfind($this->encodePath($path), array('{DAV:}quota-available-bytes'));
+ $response = $this->client->propfind($this->encodePath($path), array('{DAV:}quota-available-bytes'));
if (isset($response['{DAV:}quota-available-bytes'])) {
return (int)$response['{DAV:}quota-available-bytes'];
} else {
return \OC\Files\SPACE_UNKNOWN;
}
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
return \OC\Files\SPACE_UNKNOWN;
}
}
- public function touch($path, $mtime=null) {
+ public function touch($path, $mtime = null) {
$this->init();
if (is_null($mtime)) {
- $mtime=time();
+ $mtime = time();
}
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
// if file exists, update the mtime, else create a new empty file
if ($this->file_exists($path)) {
try {
$this->client->proppatch($this->encodePath($path), array('{DAV:}lastmodified' => $mtime));
- }
- catch (\Sabre_DAV_Exception_NotImplemented $e) {
+ } catch (\Sabre_DAV_Exception_NotImplemented $e) {
return false;
}
} else {
@@ -261,23 +261,13 @@ class DAV extends \OC\Files\Storage\Common{
return true;
}
- /**
- * @param string $path
- * @param string $target
- */
- public function getFile($path, $target) {
- $this->init();
- $source=$this->fopen($path, 'r');
- file_put_contents($target, $source);
- }
-
- public function uploadFile($path, $target) {
+ protected function uploadFile($path, $target) {
$this->init();
- $source=fopen($path, 'r');
+ $source = fopen($path, 'r');
$curl = curl_init();
- curl_setopt($curl, CURLOPT_USERPWD, $this->user.':'.$this->password);
- curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().str_replace(' ', '%20', $target));
+ curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password);
+ curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . str_replace(' ', '%20', $target));
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path));
@@ -285,26 +275,29 @@ class DAV extends \OC\Files\Storage\Common{
if ($this->secure === true) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
- if($this->certPath){
+ if ($this->certPath) {
curl_setopt($curl, CURLOPT_CAINFO, $this->certPath);
}
}
- curl_exec ($curl);
+ curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode !== 200) {
\OCP\Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, \OCP\Util::ERROR);
}
- curl_close ($curl);
+ curl_close($curl);
+ $this->removeCachedFile($target);
}
public function rename($path1, $path2) {
$this->init();
$path1 = $this->encodePath($this->cleanPath($path1));
- $path2 = $this->createBaseUri().$this->encodePath($this->cleanPath($path2));
+ $path2 = $this->createBaseUri() . $this->encodePath($this->cleanPath($path2));
try {
- $this->client->request('MOVE', $path1, null, array('Destination'=>$path2));
+ $this->client->request('MOVE', $path1, null, array('Destination' => $path2));
+ $this->removeCachedFile($path1);
+ $this->removeCachedFile($path2);
return true;
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
return false;
}
}
@@ -312,47 +305,48 @@ class DAV extends \OC\Files\Storage\Common{
public function copy($path1, $path2) {
$this->init();
$path1 = $this->encodePath($this->cleanPath($path1));
- $path2 = $this->createBaseUri().$this->encodePath($this->cleanPath($path2));
+ $path2 = $this->createBaseUri() . $this->encodePath($this->cleanPath($path2));
try {
- $this->client->request('COPY', $path1, null, array('Destination'=>$path2));
+ $this->client->request('COPY', $path1, null, array('Destination' => $path2));
+ $this->removeCachedFile($path2);
return true;
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
return false;
}
}
public function stat($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
$response = $this->client->propfind($this->encodePath($path), array('{DAV:}getlastmodified', '{DAV:}getcontentlength'));
return array(
- 'mtime'=>strtotime($response['{DAV:}getlastmodified']),
- 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0,
+ 'mtime' => strtotime($response['{DAV:}getlastmodified']),
+ 'size' => (int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0,
);
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
return array();
}
}
public function getMimeType($path) {
$this->init();
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
- $response=$this->client->propfind($this->encodePath($path), array('{DAV:}getcontenttype', '{DAV:}resourcetype'));
+ $response = $this->client->propfind($this->encodePath($path), array('{DAV:}getcontenttype', '{DAV:}resourcetype'));
$responseType = array();
if (isset($response["{DAV:}resourcetype"])) {
- $responseType=$response["{DAV:}resourcetype"]->resourceType;
+ $responseType = $response["{DAV:}resourcetype"]->resourceType;
}
- $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
- if ($type=='dir') {
+ $type = (count($responseType) > 0 and $responseType[0] == "{DAV:}collection") ? 'dir' : 'file';
+ if ($type == 'dir') {
return 'httpd/unix-directory';
} elseif (isset($response['{DAV:}getcontenttype'])) {
return $response['{DAV:}getcontenttype'];
} else {
return false;
}
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
return false;
}
}
@@ -368,6 +362,7 @@ class DAV extends \OC\Files\Storage\Common{
/**
* URL encodes the given path but keeps the slashes
+ *
* @param string $path to encode
* @return string encoded path
*/
@@ -382,11 +377,11 @@ class DAV extends \OC\Files\Storage\Common{
* @param integer $expected
*/
private function simpleResponse($method, $path, $body, $expected) {
- $path=$this->cleanPath($path);
+ $path = $this->cleanPath($path);
try {
- $response=$this->client->request($method, $this->encodePath($path), $body);
- return $response['statusCode']==$expected;
- } catch(\Exception $e) {
+ $response = $this->client->request($method, $this->encodePath($path), $body);
+ return $response['statusCode'] == $expected;
+ } catch (\Exception $e) {
return false;
}
}
diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php
index 90f5e159535..90d7afed28b 100755
--- a/apps/files_external/personal.php
+++ b/apps/files_external/personal.php
@@ -22,9 +22,8 @@
OCP\Util::addScript('files_external', 'settings');
OCP\Util::addStyle('files_external', 'settings');
-$backends = OC_Mount_Config::getBackends();
-// Remove local storage
-unset($backends['\OC\Files\Storage\Local']);
+$backends = OC_Mount_Config::getPersonalBackends();
+
$tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('isAdminPage', false);
$tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints());
diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php
index 31183409e39..5b62b542200 100644
--- a/apps/files_external/settings.php
+++ b/apps/files_external/settings.php
@@ -26,10 +26,26 @@ OCP\Util::addScript('files_external', 'settings');
OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min');
OCP\Util::addStyle('files_external', 'settings');
OCP\Util::addStyle('3rdparty', 'chosen/chosen');
+
+$backends = OC_Mount_Config::getBackends();
+$personal_backends = array();
+$enabled_backends = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
+foreach ($backends as $class => $backend)
+{
+ if ($class != '\OC\Files\Storage\Local')
+ {
+ $personal_backends[$class] = array(
+ 'backend' => $backend['backend'],
+ 'enabled' => in_array($class, $enabled_backends),
+ );
+ }
+}
+
$tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('isAdminPage', true);
$tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
-$tmpl->assign('backends', OC_Mount_Config::getBackends());
+$tmpl->assign('backends', $backends);
+$tmpl->assign('personal_backends', $personal_backends);
$tmpl->assign('groups', OC_Group::getGroups());
$tmpl->assign('users', OCP\User::getUsers());
$tmpl->assign('userDisplayNames', OC_User::getDisplayNames());
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 3ca16c3c7a8..de44d3c8644 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -122,12 +122,18 @@
<?php if ($_['isAdminPage']): ?>
<br />
- <input type="checkbox"
- name="allowUserMounting"
- id="allowUserMounting"
- value="1" <?php if ($_['allowUserMounting'] == 'yes') print_unescaped(' checked="checked"'); ?> />
- <label for="allowUserMounting"><?php p($l->t('Enable User External Storage')); ?></label><br/>
- <em><?php p($l->t('Allow users to mount their own external storage')); ?></em>
+ <input type="checkbox" name="allowUserMounting" id="allowUserMounting"
+ value="1" <?php if ($_['allowUserMounting'] == 'yes') print_unescaped(' checked="checked"'); ?> />
+ <label for="allowUserMounting"><?php p($l->t('Enable User External Storage')); ?></label> <span id="userMountingMsg" class="msg"></span>
+
+ <p id="userMountingBackups"<?php if ($_['allowUserMounting'] != 'yes'): ?> class="hidden"<?php endif; ?>>
+ <?php p($l->t('Allow users to mount the following external storage')); ?><br />
+ <?php $i = 0; foreach ($_['personal_backends'] as $class => $backend): ?>
+ <input type="checkbox" id="allowUserMountingBackends<?php p($i); ?>" name="allowUserMountingBackends[]" value="<?php p($class); ?>" <?php if ($backend['enabled']) print_unescaped(' checked="checked"'); ?> />
+ <label for="allowUserMountingBackends<?php p($i); ?>"><?php p($backend['backend']); ?></label> <br />
+ <?php $i++; ?>
+ <?php endforeach; ?>
+ </p>
<?php endif; ?>
</fieldset>
</form>
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 3469829b6f7..9417a6eeb89 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -1,4 +1,5 @@
<?php
+/** @var $this OC_Router */
$this->create('core_ajax_public_preview', '/publicpreview.png')->action(
function() {
require_once __DIR__ . '/../ajax/publicpreview.php';
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 36de452a55e..9f0ed12f935 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -5,6 +5,14 @@ $(document).ready(function() {
if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) {
$('#fileList').on('fileActionsReady',function(){
+
+ var allShared = $('#fileList').find('[data-share-owner]').find('[data-Action="Share"]');
+ allShared.addClass('permanent');
+ allShared.find('span').text(function(){
+ $owner = $(this).closest('tr').attr('data-share-owner');
+ return ' ' + t('files_sharing', 'Shared by {owner}', {owner: $owner});
+ });
+
if (!sharesLoaded){
OC.Share.loadIcons('file');
// assume that we got all shares, so switching directories
@@ -17,16 +25,15 @@ $(document).ready(function() {
});
FileActions.register('all', 'Share', OC.PERMISSION_READ, OC.imagePath('core', 'actions/share'), function(filename) {
- if ($('#dir').val() == '/') {
- var item = $('#dir').val() + filename;
- } else {
- var item = $('#dir').val() + '/' + filename;
+ var dir = $('#dir').val();
+ var item = dir + '/' + filename;
+ if (dir == '/') {
+ item = dir + filename;
}
var tr = FileList.findFileEl(filename);
+ var itemType = 'file';
if ($(tr).data('type') == 'dir') {
- var itemType = 'folder';
- } else {
- var itemType = 'file';
+ itemType = 'folder';
}
var possiblePermissions = $(tr).data('permissions');
var appendTo = $(tr).find('td.filename');
diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php
index 19a2d22b068..0ba58aa896a 100644
--- a/apps/files_sharing/lib/api.php
+++ b/apps/files_sharing/lib/api.php
@@ -172,12 +172,12 @@ class Api {
// workaround because folders are named 'dir' in this context
$itemType = $file['type'] === 'file' ? 'file' : 'folder';
$share = \OCP\Share::getItemShared($itemType, $file['fileid']);
- $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']);
- if ($receivedFrom) {
- $share['received_from'] = $receivedFrom['uid_owner'];
- $share['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']);
- }
- if ($share) {
+ if($share) {
+ $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']);
+ if ($receivedFrom) {
+ $share['received_from'] = $receivedFrom['uid_owner'];
+ $share['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']);
+ }
$result = array_merge($result, $share);
}
}
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index 4b0da0b002d..10f2182655f 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -137,9 +137,12 @@ class Shared_Cache extends Cache {
} else {
$cache = $this->getSourceCache($folder);
if ($cache) {
+ $parent = $this->storage->getFile($folder);
$sourceFolderContent = $cache->getFolderContents($this->files[$folder]);
foreach ($sourceFolderContent as $key => $c) {
$sourceFolderContent[$key]['usersPath'] = 'files/Shared/' . $folder . '/' . $c['name'];
+ $sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner'];
+ $sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner'];
}
return $sourceFolderContent;
diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php
index ec0f368386f..5e00050fe1e 100644
--- a/apps/files_sharing/lib/share/file.php
+++ b/apps/files_sharing/lib/share/file.php
@@ -94,6 +94,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
$file['mtime'] = $item['mtime'];
$file['encrypted'] = $item['encrypted'];
$file['etag'] = $item['etag'];
+ $file['uid_owner'] = $item['uid_owner'];
+ $file['displayname_owner'] = $item['displayname_owner'];
+
$storage = \OC\Files\Filesystem::getStorage('/');
$cache = $storage->getCache();
if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) {
diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php
index 928be93fc96..19b1fb27630 100644
--- a/apps/files_sharing/templates/authenticate.php
+++ b/apps/files_sharing/templates/authenticate.php
@@ -8,7 +8,10 @@
<?php endif; ?>
<p class="infield">
<label for="password" class="infield"><?php p($l->t('Password')); ?></label>
- <input type="password" name="password" id="password" placeholder="" value="" autofocus />
+ <input type="password" name="password" id="password"
+ placeholder="" value=""
+ autocomplete="off" autocapitalize="off" autocorrect="off"
+ autofocus />
<input type="submit" value="" class="svg icon icon-confirm" />
</p>
</fieldset>
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 1278e0c4d1f..0d3d9b98b2e 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -33,13 +33,16 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
parent::setUp();
$this->folder = '/folder_share_api_test';
+ $this->subfolder = '/subfolder_share_api_test';
$this->filename = 'share-api-test.txt';
// save file with content
$this->view->file_put_contents($this->filename, $this->data);
$this->view->mkdir($this->folder);
+ $this->view->mkdir($this->folder . '/' . $this->subfolder);
$this->view->file_put_contents($this->folder.'/'.$this->filename, $this->data);
+ $this->view->file_put_contents($this->folder.'/' . $this->subfolder . '/' .$this->filename, $this->data);
}
function tearDown() {
@@ -287,6 +290,71 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
}
/**
+ * @brief share a folder, than reshare a file within the shared folder and check if we construct the correct path
+ * @medium
+ */
+ function testGetShareFromFolderReshares() {
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $fileInfo1 = $this->view->getFileInfo($this->folder);
+ $fileInfo2 = $this->view->getFileInfo($this->folder.'/'.$this->filename);
+ $fileInfo3 = $this->view->getFileInfo($this->folder.'/' . $this->subfolder . '/' .$this->filename);
+
+ // share root folder to user2
+ $result = \OCP\Share::shareItem('folder', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER,
+ \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
+
+ // share was successful?
+ $this->assertTrue($result);
+
+ // login as user2
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // share file in root folder
+ $result = \OCP\Share::shareItem('file', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, 1);
+ // share was successful?
+ $this->assertTrue(is_string($result));
+
+ // share file in subfolder
+ $result = \OCP\Share::shareItem('file', $fileInfo3['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, 1);
+ // share was successful?
+ $this->assertTrue(is_string($result));
+
+ $testValues=array(
+ array('query' => 'Shared/' . $this->folder,
+ 'expectedResult' => '/Shared' . $this->folder . '/' . $this->filename),
+ array('query' => 'Shared/' . $this->folder . $this->subfolder,
+ 'expectedResult' => '/Shared' . $this->folder . $this->subfolder . '/' . $this->filename),
+ );
+ foreach ($testValues as $value) {
+
+ $_GET['path'] = $value['query'];
+ $_GET['subfiles'] = 'true';
+
+ $result = Share\Api::getAllShares(array());
+
+ $this->assertTrue($result->succeeded());
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ $this->assertEquals($value['expectedResult'], $data[0]['path']);
+ }
+
+ // cleanup
+
+ \OCP\Share::unshare('file', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+ \OCP\Share::unshare('file', $fileInfo3['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ \OCP\Share::unshare('folder', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER,
+ \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
+
+ }
+
+ /**
* @medium
*/
function testGetShareFromUnknownId() {
diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php
index 3e283271f5d..d44972d01f1 100644
--- a/apps/files_sharing/tests/base.php
+++ b/apps/files_sharing/tests/base.php
@@ -43,6 +43,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {
*/
public $view;
public $folder;
+ public $subfolder;
public static function setUpBeforeClass() {
// reset backend
diff --git a/apps/user_ldap/lib/helper.php b/apps/user_ldap/lib/helper.php
index 7de7fe8667f..b5955cb2abb 100644
--- a/apps/user_ldap/lib/helper.php
+++ b/apps/user_ldap/lib/helper.php
@@ -120,7 +120,7 @@ class Helper {
$saveOtherConfigurations = '';
if(empty($prefix)) {
- $saveOtherConfigurations = 'AND `Configkey` NOT LIKE \'s%\'';
+ $saveOtherConfigurations = 'AND `configkey` NOT LIKE \'s%\'';
}
$query = \OCP\DB::prepare('
diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php
index 5ad127197f3..2cb3dfb2c60 100644
--- a/apps/user_ldap/user_proxy.php
+++ b/apps/user_ldap/user_proxy.php
@@ -54,11 +54,15 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
protected function walkBackends($uid, $method, $parameters) {
$cacheKey = $this->getUserCacheKey($uid);
foreach($this->backends as $configPrefix => $backend) {
-// print("walkBackend '$configPrefix'<br/>");
- if($result = call_user_func_array(array($backend, $method), $parameters)) {
+ $instance = $backend;
+ if(!method_exists($instance, $method)
+ && method_exists($this->getAccess($configPrefix), $method)) {
+ $instance = $this->getAccess($configPrefix);
+ }
+ if($result = call_user_func_array(array($instance, $method), $parameters)) {
$this->writeToCache($cacheKey, $configPrefix);
return $result;
- }
+ }
}
return false;
}
@@ -77,7 +81,12 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
//in case the uid has been found in the past, try this stored connection first
if(!is_null($prefix)) {
if(isset($this->backends[$prefix])) {
- $result = call_user_func_array(array($this->backends[$prefix], $method), $parameters);
+ $instance = $this->backends[$prefix];
+ if(!method_exists($instance, $method)
+ && method_exists($this->getAccess($prefix), $method)) {
+ $instance = $this->getAccess($prefix);
+ }
+ $result = call_user_func_array(array($instance, $method), $parameters);
if($result === $passOnWhen) {
//not found here, reset cache to null if user vanished
//because sometimes methods return false with a reason
diff --git a/config/config.sample.php b/config/config.sample.php
index 9c5eca8a5ec..987a866e49b 100755
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -178,6 +178,9 @@ $CONFIG = array(
/* Enable or disable the logging of IP addresses in case of webform auth failures */
"log_authfailip" => false,
+/* Whether http-basic username must equal username to login */
+"basic_auth" => true,
+
/*
* Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
* This rotates the current owncloud logfile to a new name, this way the total log usage
diff --git a/core/css/apps.css b/core/css/apps.css
index f68f53d6999..58f2759f69a 100644
--- a/core/css/apps.css
+++ b/core/css/apps.css
@@ -187,6 +187,9 @@
}
#app-settings.open #app-settings-content {
display: block;
+ /* restrict height of settings and make scrollable */
+ max-height: 300px;
+ overflow-y: scroll;
}
.settings-button {
diff --git a/core/css/icons.css b/core/css/icons.css
index 814749c5af8..cdfdd8e43ef 100644
--- a/core/css/icons.css
+++ b/core/css/icons.css
@@ -1,4 +1,4 @@
-.icon {
+[class^="icon-"], [class*=" icon-"] {
background-repeat: no-repeat;
background-position: center;
}
@@ -24,7 +24,7 @@
.icon-noise {
background-image: url('../img/noise.png');
- background-repeat: no-repeat;
+ background-repeat: repeat;
}
@@ -66,7 +66,8 @@
.icon-delete {
background-image: url('../img/actions/delete.svg');
}
-.icon-delete-hover {
+.icon-delete:hover,
+.icon-delete:focus {
background-image: url('../img/actions/delete-hover.svg');
}
@@ -155,11 +156,15 @@
background-image: url('../img/actions/sound-off.svg');
}
-.icon-star {
+.icon-star,
+.icon-starred:hover,
+.icon-starred:focus {
background-image: url('../img/actions/star.svg');
}
-.icon-starred {
+.icon-starred,
+.icon-star:hover,
+.icon-star:focus {
background-image: url('../img/actions/starred.svg');
}
diff --git a/core/css/styles.css b/core/css/styles.css
index 341a507ce37..69cf6df07d0 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -175,6 +175,7 @@ button, .button,
border: 1px solid rgba(190,190,190,.9);
cursor: pointer;
border-radius: 3px;
+ outline: none;
}
input[type="submit"]:hover, input[type="submit"]:focus,
input[type="button"]:hover, input[type="button"]:focus,
@@ -204,18 +205,18 @@ textarea:disabled {
/* Primary action button, use sparingly */
.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary {
border: 1px solid #1d2d44;
- background: #35537a;
+ background-color: #35537a;
color: #ddd;
}
.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,
.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {
border: 1px solid #1d2d44;
- background: #304d76;
+ background-color: #304d76;
color: #fff;
}
.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {
border: 1px solid #1d2d44;
- background: #1d2d44;
+ background-color: #1d2d44;
color: #bbb;
}
@@ -233,7 +234,7 @@ textarea:disabled {
}
input[type="submit"].enabled {
- background: #66f866;
+ background-color: #66f866;
border: 1px solid #5e5;
}
@@ -405,11 +406,9 @@ input[name="adminpass-clone"] { padding-left:1.8em; width:11.7em !important; }
/* General new input field look */
#body-login input[type="text"],
#body-login input[type="password"],
-#body-login input[type="email"] {
- border: 1px solid #323233;
- border-radius: 5px;
-}
-#body-login input[type='submit'] {
+#body-login input[type="email"],
+#body-login input[type="submit"] {
+ border: none;
border-radius: 5px;
}
diff --git a/core/img/logo-mail.gif b/core/img/logo-mail.gif
index 6a1caaa9188..f1dd108450e 100644
--- a/core/img/logo-mail.gif
+++ b/core/img/logo-mail.gif
Binary files differ
diff --git a/core/js/config.php b/core/js/config.php
index c606ef35056..7e23f3e2e41 100644
--- a/core/js/config.php
+++ b/core/js/config.php
@@ -61,8 +61,10 @@ $array = array(
"firstDay" => json_encode($l->l('firstday', 'firstday')) ,
"oc_config" => json_encode(
array(
- 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')),
- 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true)
+ 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')),
+ 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true),
+ 'version' => implode('.', OC_Util::getVersion()),
+ 'versionstring' => OC_Util::getVersionString(),
)
),
"oc_defaults" => json_encode(
diff --git a/core/js/core.json b/core/js/core.json
index 4beab7cf796..665e2485a90 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -17,7 +17,6 @@
"eventsource.js",
"config.js",
"multiselect.js",
- "router.js",
"oc-requesttoken.js"
]
}
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 02a40c088b4..381c42d9dbb 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -75,31 +75,32 @@
var $div = this;
- OC.Router.registerLoadedCallback(function() {
- var url = OC.Router.generate('core_avatar_get', {user: user, size: size})+'?requesttoken='+oc_requesttoken;
- $.get(url, function(result) {
- if (typeof(result) === 'object') {
- if (!hidedefault) {
- if (result.data && result.data.displayname) {
- $div.imageplaceholder(user, result.data.displayname);
- } else {
- $div.imageplaceholder(user);
- }
+ var url = OC.generateUrl(
+ '/avatar/{user}/{size}?requesttoken={requesttoken}',
+ {user: user, size: size, requesttoken: oc_requesttoken});
+
+ $.get(url, function(result) {
+ if (typeof(result) === 'object') {
+ if (!hidedefault) {
+ if (result.data && result.data.displayname) {
+ $div.imageplaceholder(user, result.data.displayname);
} else {
- $div.hide();
+ $div.imageplaceholder(user);
}
} else {
- $div.show();
- if (ie8fix === true) {
- $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
- } else {
- $div.html('<img src="'+url+'">');
- }
+ $div.hide();
}
- if(typeof callback === 'function') {
- callback();
+ } else {
+ $div.show();
+ if (ie8fix === true) {
+ $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
+ } else {
+ $div.html('<img src="'+url+'">');
}
- });
+ }
+ if(typeof callback === 'function') {
+ callback();
+ }
});
};
}(jQuery));
diff --git a/core/js/js.js b/core/js/js.js
index ec890be4541..77aadd23e03 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -194,6 +194,30 @@ var OC={
linkToRemoteBase:function(service) {
return OC.webroot + '/remote.php/' + service;
},
+
+ /**
+ * Generates the absolute url for the given relative url, which can contain parameters.
+ *
+ * @returns {string}
+ * @param {string} url
+ * @param params
+ */
+ generateUrl: function(url, params) {
+ var _build = function (text, vars) {
+ return text.replace(/{([^{}]*)}/g,
+ function (a, b) {
+ var r = vars[b];
+ return typeof r === 'string' || typeof r === 'number' ? r : a;
+ }
+ );
+ };
+ if (url.charAt(0) !== '/') {
+ url = '/' + url;
+
+ }
+ return OC.webroot + '/index.php' + _build(url, params);
+ },
+
/**
* @brief Creates an absolute url for remote use
* @param string $service id
@@ -467,6 +491,34 @@ OC.search.lastResults={};
OC.addStyle.loaded=[];
OC.addScript.loaded=[];
+OC.msg={
+ startSaving:function(selector){
+ OC.msg.startAction(selector, t('core', 'Saving...'));
+ },
+ finishedSaving:function(selector, data){
+ OC.msg.finishedAction(selector, data);
+ },
+ startAction:function(selector, message){
+ $(selector)
+ .html( message )
+ .removeClass('success')
+ .removeClass('error')
+ .stop(true, true)
+ .show();
+ },
+ finishedAction:function(selector, data){
+ if( data.status === "success" ){
+ $(selector).html( data.data.message )
+ .addClass('success')
+ .stop(true, true)
+ .delay(3000)
+ .fadeOut(900);
+ }else{
+ $(selector).html( data.data.message ).addClass('error');
+ }
+ }
+};
+
OC.Notification={
queuedNotifications: [],
getDefaultNotificationFunction: null,
@@ -763,12 +815,10 @@ function initCore() {
if (interval < 60) {
interval = 60;
}
- OC.Router.registerLoadedCallback(function(){
- var url = OC.Router.generate('heartbeat');
- setInterval(function(){
- $.post(url);
- }, interval * 1000);
- });
+ var url = OC.generateUrl('/heartbeat');
+ setInterval(function(){
+ $.post(url);
+ }, interval * 1000);
}
// session heartbeat (defaults to enabled)
diff --git a/core/js/router.js b/core/js/router.js
deleted file mode 100644
index e6ef54a1864..00000000000
--- a/core/js/router.js
+++ /dev/null
@@ -1,81 +0,0 @@
-OC.router_base_url = OC.webroot + '/index.php';
-OC.Router = {
- // register your ajax requests to load after the loading of the routes
- // has finished. otherwise you face problems with race conditions
- registerLoadedCallback: function(callback){
- if (!this.routes_request){
- return;
- }
- this.routes_request.done(callback);
- },
- routes_request: !window.TESTING && $.ajax(OC.router_base_url + '/core/routes.json', {
- dataType: 'json',
- success: function(jsondata) {
- if (jsondata.status === 'success') {
- OC.Router.routes = jsondata.data;
- }
- }
- }),
- generate:function(name, opt_params) {
- if (!('routes' in this)) {
- if(this.routes_request.state() != 'resolved') {
- console.warn('To avoid race conditions, please register a callback');// wait
- }
- }
- if (!(name in this.routes)) {
- throw new Error('The route "' + name + '" does not exist.');
- }
- var route = this.routes[name];
- var params = opt_params || {};
- var unusedParams = $.extend(true, {}, params);
- var url = '';
- var optional = true;
- $(route.tokens).each(function(i, token) {
- if ('text' === token[0]) {
- url = token[1] + url;
- optional = false;
-
- return;
- }
-
- if ('variable' === token[0]) {
- if (false === optional || !(token[3] in route.defaults)
- || ((token[3] in params) && params[token[3]] != route.defaults[token[3]])) {
- var value;
- if (token[3] in params) {
- value = params[token[3]];
- delete unusedParams[token[3]];
- } else if (token[3] in route.defaults) {
- value = route.defaults[token[3]];
- } else if (optional) {
- return;
- } else {
- throw new Error('The route "' + name + '" requires the parameter "' + token[3] + '".');
- }
-
- var empty = true === value || false === value || '' === value;
-
- if (!empty || !optional) {
- url = token[1] + encodeURIComponent(value).replace(/%2F/g, '/') + url;
- }
-
- optional = false;
- }
-
- return;
- }
-
- throw new Error('The token type "' + token[0] + '" is not supported.');
- });
- if (url === '') {
- url = '/';
- }
-
- unusedParams = $.param(unusedParams);
- if (unusedParams.length > 0) {
- url += '?'+unusedParams;
- }
-
- return OC.router_base_url + url;
- }
-}
diff --git a/core/js/setup.js b/core/js/setup.js
index 279b5fbebb9..96719540f96 100644
--- a/core/js/setup.js
+++ b/core/js/setup.js
@@ -36,6 +36,7 @@ $(document).ready(function() {
$('#showAdvanced').click(function() {
$('#datadirContent').slideToggle(250);
+ $('#databaseBackend').slideToggle(250);
$('#databaseField').slideToggle(250);
});
$("form").submit(function(){
@@ -73,6 +74,7 @@ $(document).ready(function() {
if (currentDbType === 'sqlite' || (dbtypes.sqlite && currentDbType === undefined)){
$('#datadirContent').hide(250);
+ $('#databaseBackend').hide(250);
$('#databaseField').hide(250);
}
diff --git a/core/js/share.js b/core/js/share.js
index 0939259b7da..129e50b22d5 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -584,8 +584,8 @@ $(document).ready(function() {
$(checkboxes).filter('input[name="edit"]').attr('checked', false);
// Check Edit if Create, Update, or Delete is checked
} else if (($(this).attr('name') == 'create'
- || $(this).attr('name') == 'update'
- || $(this).attr('name') == 'delete'))
+ || $(this).attr('name') == 'update'
+ || $(this).attr('name') == 'delete'))
{
$(checkboxes).filter('input[name="edit"]').attr('checked', true);
}
diff --git a/core/js/tags.js b/core/js/tags.js
index bc6d7b4e071..bc2b42bf5ff 100644
--- a/core/js/tags.js
+++ b/core/js/tags.js
@@ -69,7 +69,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_ids_for_tag', {type: type});
+ url = OC.generateUrl('/tags/{type}/ids', {type: type});
$.getJSON(url, {tag: tag}, function(response) {
if(response.status === 'success') {
defer.resolve(response.ids);
@@ -90,7 +90,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_favorites', {type: type});
+ url = OC.generateUrl('/tags/{type}/favorites', {type: type});
$.getJSON(url, function(response) {
if(response.status === 'success') {
defer.resolve(response.ids);
@@ -111,7 +111,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_tags', {type: type});
+ url = OC.generateUrl('/tags/{type}', {type: type});
$.getJSON(url, function(response) {
if(response.status === 'success') {
defer.resolve(response.tags);
@@ -133,7 +133,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_tag', {type: type, id: id});
+ url = OC.generateUrl('/tags/{type}/tag/{id}/', {type: type, id: id});
$.post(url, {tag: tag}, function(response) {
if(response.status === 'success') {
defer.resolve(response);
@@ -157,7 +157,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_untag', {type: type, id: id});
+ url = OC.generateUrl('/tags/{type}/untag/{id}/', {type: type, id: id});
$.post(url, {tag: tag}, function(response) {
if(response.status === 'success') {
defer.resolve(response);
@@ -181,7 +181,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_favorite', {type: type, id: id});
+ url = OC.generateUrl('/tags/{type}/favorite/{id}/', {type: type, id: id});
$.post(url, function(response) {
if(response.status === 'success') {
defer.resolve(response);
@@ -205,7 +205,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_unfavorite', {type: type, id: id});
+ url = OC.generateUrl('/tags/{type}/unfavorite/{id}/', {type: type, id: id});
$.post(url, function(response) {
if(response.status === 'success') {
defer.resolve();
@@ -229,7 +229,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_add', {type: type});
+ url = OC.generateUrl('/tags/{type}/add', {type: type});
$.post(url,{tag:tag}, function(response) {
if(typeof cb == 'function') {
cb(response);
@@ -256,7 +256,7 @@ OC.Tags= {
type = type ? type : this.type;
var defer = $.Deferred(),
self = this,
- url = OC.Router.generate('core_tags_delete', {type: type});
+ url = OC.generateUrl('/tags/{type}/delete', {type: type});
if(!tags || !tags.length) {
throw new Error(t('core', 'No tags selected for deletion.'));
}
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index b1193240580..d86cd81cda8 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -68,9 +68,14 @@ window.oc_defaults = {};
// global setup for all tests
(function setupTests() {
var fakeServer = null,
+ $testArea = null,
routesRequestStub;
beforeEach(function() {
+ // test area for elements that need absolute selector access or measure widths/heights
+ // which wouldn't work for detached or hidden elements
+ $testArea = $('<div id="testArea" style="position: absolute; width: 1280px; height: 800px; top: -3000px; left: -3000px;"></div>');
+ $('body').append($testArea);
// enforce fake XHR, tests should not depend on the server and
// must use fake responses for expected calls
fakeServer = sinon.fakeServer.create();
@@ -86,21 +91,14 @@ window.oc_defaults = {};
// make it globally available, so that other tests can define
// custom responses
window.fakeServer = fakeServer;
-
- OC.Router.routes = [];
- OC.Router.routes_request = {
- state: sinon.stub().returns('resolved'),
- done: sinon.stub()
- };
});
afterEach(function() {
- OC.Router.routes_request.state.reset();
- OC.Router.routes_request.done.reset();
-
// uncomment this to log requests
// console.log(window.fakeServer.requests);
fakeServer.restore();
+
+ $testArea.remove();
});
})();
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 478505e9287..069546387c7 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -179,7 +179,7 @@ describe('Core base tests', function() {
});
it('Encodes special characters', function() {
expect(OC.buildQueryString({
- unicode: '汉字',
+ unicode: '汉字'
})).toEqual('unicode=%E6%B1%89%E5%AD%97');
expect(OC.buildQueryString({
b: 'spaace value',
@@ -199,22 +199,20 @@ describe('Core base tests', function() {
'booleantrue': true
})).toEqual('booleanfalse=false&booleantrue=true');
expect(OC.buildQueryString({
- 'number': 123,
+ 'number': 123
})).toEqual('number=123');
});
});
describe('Session heartbeat', function() {
var clock,
oldConfig,
- loadedStub,
routeStub,
counter;
beforeEach(function() {
clock = sinon.useFakeTimers();
oldConfig = window.oc_config;
- loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback');
- routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat');
+ routeStub = sinon.stub(OC, 'generateUrl').returns('/heartbeat');
counter = 0;
fakeServer.autoRespond = true;
@@ -227,7 +225,6 @@ describe('Core base tests', function() {
afterEach(function() {
clock.restore();
window.oc_config = oldConfig;
- loadedStub.restore();
routeStub.restore();
});
it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
@@ -236,9 +233,7 @@ describe('Core base tests', function() {
session_lifetime: 300
};
window.initCore();
- expect(loadedStub.calledOnce).toEqual(true);
- loadedStub.yield();
- expect(routeStub.calledWith('heartbeat')).toEqual(true);
+ expect(routeStub.calledWith('/heartbeat')).toEqual(true);
expect(counter).toEqual(0);
@@ -264,7 +259,6 @@ describe('Core base tests', function() {
session_lifetime: 300
};
window.initCore();
- expect(loadedStub.notCalled).toEqual(true);
expect(routeStub.notCalled).toEqual(true);
expect(counter).toEqual(0);
@@ -276,5 +270,14 @@ describe('Core base tests', function() {
});
});
+ describe('Generate Url', function() {
+ it('returns absolute urls', function() {
+ expect(OC.generateUrl('heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
+ expect(OC.generateUrl('/heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
+ });
+ it('substitutes parameters', function() {
+ expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt');
+ });
+ });
});
diff --git a/core/lostpassword/controller.php b/core/lostpassword/controller.php
index fd20c6ba249..c858696885b 100644
--- a/core/lostpassword/controller.php
+++ b/core/lostpassword/controller.php
@@ -69,7 +69,7 @@ class Controller {
$defaults = new \OC_Defaults();
\OC_Mail::send($email, $_POST['user'], $l->t('%s password reset', array($defaults->getName())), $msg, $from, $defaults->getName());
} catch (Exception $e) {
- \OC_Template::printErrorPage( 'A problem occurs during sending the e-mail please contact your administrator.');
+ \OC_Template::printErrorPage( $l->t('A problem has occurred whilst sending the email, please contact your administrator.') );
}
self::displayLostPasswordPage(false, true);
} else {
diff --git a/core/routes.php b/core/routes.php
index aea788bdc6b..76cf03c3673 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -65,8 +65,6 @@ $this->create('core_tags_delete', '/tags/{type}/delete')
$this->create('js_config', '/core/js/oc.js')
->actionInclude('core/js/config.php');
// Routing
-$this->create('core_ajax_routes', '/core/routes.json')
- ->action('OC_Router', 'JSRoutes');
$this->create('core_ajax_preview', '/core/preview.png')
->actionInclude('core/ajax/preview.php');
$this->create('core_lostpassword_index', '/lostpassword/')
diff --git a/core/templates/installation.php b/core/templates/installation.php
index d3adb34f412..e2d296a713f 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -67,7 +67,7 @@
<?php if(!$_['directoryIsSet'] OR !$_['dbIsSet'] OR count($_['errors']) > 0): ?>
<fieldset id="advancedHeader">
- <legend><a id="showAdvanced"><?php p($l->t( 'Advanced' )); ?> <img class="svg" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" /></a></legend>
+ <legend><a id="showAdvanced"><?php p($l->t( 'Storage & database' )); ?> <img class="svg" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" /></a></legend>
</fieldset>
<?php endif; ?>
@@ -84,7 +84,7 @@
<?php endif; ?>
<?php if(!$_['dbIsSet'] OR count($_['errors']) > 0): ?>
- <fieldset id='databaseField'>
+ <fieldset id='databaseBackend'>
<?php if($_['hasMySQL'] or $_['hasPostgreSQL'] or $_['hasOracle'] or $_['hasMSSQL'])
$hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?>
<legend><?php p($l->t( 'Configure the database' )); ?></legend>
@@ -100,8 +100,10 @@
<?php endif; ?>
<?php endforeach; ?>
</div>
+ </fieldset>
<?php if($hasOtherDB): ?>
+ <fieldset id='databaseField'>
<div id="use_other_db">
<p class="infield grouptop">
<label for="dbuser" class="infield"><?php p($l->t( 'Database user' )); ?></label>
@@ -141,8 +143,8 @@
autocomplete="off" autocapitalize="off" autocorrect="off" />
</p>
</div>
+ </fieldset>
<?php endif; ?>
- </fieldset>
<?php endif; ?>
<div class="buttons"><input type="submit" class="primary" value="<?php p($l->t( 'Finish setup' )); ?>" data-finishing="<?php p($l->t( 'Finishing …' )); ?>" /></div>
diff --git a/core/templates/mail.php b/core/templates/mail.php
index b8b0a2bfe96..ae46eaca788 100644
--- a/core/templates/mail.php
+++ b/core/templates/mail.php
@@ -2,15 +2,15 @@
<tr><td>
<table cellspacing="0" cellpadding="0" border="0" width="600px">
<tr>
-<td bgcolor="#1d2d44" width="20px">&nbsp;</td>
-<td bgcolor="#1d2d44">
-<img src="<?php print_unescaped(OC_Helper::makeURLAbsolute(image_path('', 'logo-mail.gif'))); ?>" alt="<?php p($theme->getName()); ?>"/>
+<td bgcolor="<?php p($theme->getMailHeaderColor());?>" width="20px">&nbsp;</td>
+<td bgcolor="<?php p($theme->getMailHeaderColor());?>">
+<img src="<?php p(OC_Helper::makeURLAbsolute(image_path('', 'logo-mail.gif'))); ?>" alt="<?php p($theme->getName()); ?>"/>
</td>
</tr>
-<tr><td bgcolor="#f8f8f8" colspan="2">&nbsp;</td></tr>
+<tr><td colspan="2">&nbsp;</td></tr>
<tr>
-<td bgcolor="#f8f8f8" width="20px">&nbsp;</td>
-<td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">
+<td width="20px">&nbsp;</td>
+<td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">
<?php
print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href="%s">View it!</a><br><br>', array($_['user_displayname'], $_['filename'], $_['link'])));
if ( isset($_['expiration']) ) {
@@ -21,17 +21,17 @@ p($l->t('Cheers!'));
?>
</td>
</tr>
-<tr><td bgcolor="#f8f8f8" colspan="2">&nbsp;</td></tr>
+<tr><td colspan="2">&nbsp;</td></tr>
<tr>
-<td bgcolor="#f8f8f8" width="20px">&nbsp;</td>
-<td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br>
+<td width="20px">&nbsp;</td>
+<td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br>
<?php p($theme->getName()); ?> -
<?php p($theme->getSlogan()); ?>
-<br><a href="<?php print_unescaped($theme->getBaseUrl()); ?>"><?php print_unescaped($theme->getBaseUrl());?></a>
+<br><a href="<?php p($theme->getBaseUrl()); ?>"><?php p($theme->getBaseUrl());?></a>
</td>
</tr>
<tr>
-<td bgcolor="#f8f8f8" colspan="2">&nbsp;</td>
+<td colspan="2">&nbsp;</td>
</tr>
</table>
</td></tr>
diff --git a/lib/base.php b/lib/base.php
index 525d290931f..86ee5349828 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -316,7 +316,6 @@ class OC {
OC_Util::addScript("config");
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search', 'result');
- OC_Util::addScript('router');
OC_Util::addScript("oc-requesttoken");
// avatars
@@ -554,7 +553,8 @@ class OC {
OC_User::useBackend(new OC_User_Database());
OC_Group::useBackend(new OC_Group_Database());
- if (isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname')
+ $basic_auth = OC_Config::getValue('basic_auth', true);
+ if ($basic_auth && isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname')
&& $_SERVER['PHP_AUTH_USER'] !== self::$session->get('loginname')) {
$sessionUser = self::$session->get('loginname');
$serverUser = $_SERVER['PHP_AUTH_USER'];
@@ -693,6 +693,22 @@ class OC {
exit();
}
+ $host = OC_Request::insecureServerHost();
+ // if the host passed in headers isn't trusted
+ if (!OC::$CLI
+ // overwritehost is always trusted
+ && OC_Request::getOverwriteHost() === null
+ && !OC_Request::isTrustedDomain($host)) {
+
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ OC_Template::printErrorPage(
+ 'You are accessing the server from an untrusted domain.',
+ 'Please contact your administrator'
+ );
+ return;
+ }
+
$request = OC_Request::getPathInfo();
if (substr($request, -3) !== '.js') { // we need these files during the upgrade
self::checkMaintenanceMode();
@@ -752,7 +768,8 @@ class OC {
OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']);
}
OC_User::logout();
- header("Location: " . OC::$WEBROOT . '/');
+ // redirect to webroot and add slash if webroot is empty
+ header("Location: " . OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : ''));
} else {
if (is_null($file)) {
$param['file'] = 'index.php';
diff --git a/lib/private/api.php b/lib/private/api.php
index 3f96196e6df..1537cc11dd0 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -270,6 +270,18 @@ class OC_API {
* @return string|false (username, or false on failure)
*/
private static function loginUser(){
+
+ // reuse existing login
+ $loggedIn = OC_User::isLoggedIn();
+ $ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false;
+ if ($loggedIn === true && $ocsApiRequest) {
+
+ // initialize the user's filesystem
+ \OC_Util::setUpFS(\OC_User::getUser());
+
+ return OC_User::getUser();
+ }
+
// basic auth
$authUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
$authPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
@@ -283,17 +295,6 @@ class OC_API {
return $authUser;
}
- // reuse existing login
- $loggedIn = OC_User::isLoggedIn();
- $ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false;
- if ($loggedIn === true && $ocsApiRequest) {
-
- // initialize the user's filesystem
- \OC_Util::setUpFS(\OC_User::getUser());
-
- return OC_User::getUser();
- }
-
return false;
}
diff --git a/lib/private/app.php b/lib/private/app.php
index 048d4d4aeb1..58bf67c1d47 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -219,6 +219,8 @@ class OC_App{
$appdata=OC_OCSClient::getApplication($app);
$download=OC_OCSClient::getApplicationDownload($app, 1);
if(isset($download['downloadlink']) and $download['downloadlink']!='') {
+ // Replace spaces in download link without encoding entire URL
+ $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']);
$info = array('source'=>'http', 'href'=>$download['downloadlink'], 'appdata'=>$appdata);
$app=OC_Installer::installApp($info);
}
diff --git a/lib/private/config.php b/lib/private/config.php
index 3649da84973..56f47256134 100644
--- a/lib/private/config.php
+++ b/lib/private/config.php
@@ -77,7 +77,7 @@ class Config {
/**
* @brief Gets a value from config.php
* @param string $key key
- * @param string|null $default = null default value
+ * @param array|bool|string|null $default = null default value
* @return string the value or $default
*
* This function gets the value from config.php. If it does not exist,
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 02d1a9f4ba2..3ed9e94d69b 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -50,7 +50,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function createFile($name, $data = null) {
- if ($name === 'Shared' && empty($this->path)) {
+ if (strtolower($name) === 'shared' && empty($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
@@ -86,7 +86,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function createDirectory($name) {
- if ($name === 'Shared' && empty($this->path)) {
+ if (strtolower($name) === 'shared' && empty($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index d2fa425b22c..accf020daa2 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -94,6 +94,9 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
}
if ($sourceDir !== $destinationDir) {
// for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
+ if (ltrim($destinationDir, '/') === '' && strtolower($sourceNode->getName()) === 'shared') {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
if (!$fs->isUpdatable($sourceDir)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php
index c050d47b499..aaf2ea543b9 100644
--- a/lib/private/db/mdb2schemamanager.php
+++ b/lib/private/db/mdb2schemamanager.php
@@ -82,6 +82,9 @@ class MDB2SchemaManager {
$platform = $this->conn->getDatabasePlatform();
foreach($schemaDiff->changedTables as $tableDiff) {
$tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
+ foreach($tableDiff->changedColumns as $column) {
+ $column->oldColumnName = $platform->quoteIdentifier($column->oldColumnName);
+ }
}
if ($generateSql) {
diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php
index f9a76786c3e..1c16d03eab2 100644
--- a/lib/private/db/mdb2schemareader.php
+++ b/lib/private/db/mdb2schemareader.php
@@ -41,7 +41,9 @@ class MDB2SchemaReader {
*/
public function loadSchemaFromFile($file) {
$schema = new \Doctrine\DBAL\Schema\Schema();
+ $loadEntities = libxml_disable_entity_loader(false);
$xml = simplexml_load_file($file);
+ libxml_disable_entity_loader($loadEntities);
foreach ($xml->children() as $child) {
/**
* @var \SimpleXMLElement $child
diff --git a/lib/private/defaults.php b/lib/private/defaults.php
index 0b97497baa1..79be211b82f 100644
--- a/lib/private/defaults.php
+++ b/lib/private/defaults.php
@@ -21,6 +21,7 @@ class OC_Defaults {
private $defaultDocBaseUrl;
private $defaultSlogan;
private $defaultLogoClaim;
+ private $defaultMailHeaderColor;
function __construct() {
$this->l = OC_L10N::get('core');
@@ -33,6 +34,7 @@ class OC_Defaults {
$this->defaultDocBaseUrl = "http://doc.owncloud.org";
$this->defaultSlogan = $this->l->t("web services under your control");
$this->defaultLogoClaim = "";
+ $this->defaultMailHeaderColor = "#1d2d44"; /* header color of mail notifications */
if (class_exists("OC_Theme")) {
$this->theme = new OC_Theme();
@@ -174,4 +176,23 @@ class OC_Defaults {
return $footer;
}
+ public function buildDocLinkToKey($key) {
+ if ($this->themeExist('buildDocLinkToKey')) {
+ return $this->theme->buildDocLinkToKey($key);
+ }
+ return $this->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key;
+ }
+
+ /**
+ * Returns mail header color
+ * @return mail header color
+ */
+ public function getMailHeaderColor() {
+ if ($this->themeExist('getMailHeaderColor')) {
+ return $this->theme->getMailHeaderColor();
+ } else {
+ return $this->defaultMailHeaderColor;
+ }
+ }
+
}
diff --git a/lib/private/files.php b/lib/private/files.php
index 656d6f044ca..7e7a27f48dc 100644
--- a/lib/private/files.php
+++ b/lib/private/files.php
@@ -21,22 +21,39 @@
*
*/
+// TODO: get rid of this using proper composer packages
+require_once 'mcnetic/phpzipstreamer/ZipStreamer.php';
+
+class GET_TYPE {
+ const FILE = 1;
+ const ZIP_FILES = 2;
+ const ZIP_DIR = 3;
+}
+
/**
- * Class for fileserver access
+ * Class for file server access
*
*/
class OC_Files {
- static $tmpFiles = array();
-
- static public function getFileInfo($path, $includeMountPoints = true){
- return \OC\Files\Filesystem::getFileInfo($path, $includeMountPoints);
- }
/**
- * @param string $path
+ * @param string $filename
+ * @param string $name
+ * @param bool $zip
*/
- static public function getDirectoryContent($path){
- return \OC\Files\Filesystem::getDirectoryContent($path);
+ private static function sendHeaders($filename, $name, $zip = false) {
+ OC_Response::setContentDispositionHeader($name, 'attachment');
+ header('Content-Transfer-Encoding: binary');
+ OC_Response::disableCaching();
+ if ($zip) {
+ header('Content-Type: application/zip');
+ } else {
+ $filesize = \OC\Files\Filesystem::filesize($filename);
+ header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename));
+ if ($filesize > -1) {
+ header("Content-Length: ".$filesize);
+ }
+ }
}
/**
@@ -54,97 +71,50 @@ class OC_Files {
$xsendfile = true;
}
- if (is_array($files) && count($files) == 1) {
+ if (is_array($files) && count($files) === 1) {
$files = $files[0];
}
if (is_array($files)) {
- self::validateZipDownload($dir, $files);
- $executionTime = intval(ini_get('max_execution_time'));
- set_time_limit(0);
- $zip = new ZipArchive();
- $filename = OC_Helper::tmpFile('.zip');
- if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
- $l = OC_L10N::get('lib');
- throw new Exception($l->t('cannot open "%s"', array($filename)));
- }
- foreach ($files as $file) {
- $file = $dir . '/' . $file;
- if (\OC\Files\Filesystem::is_file($file)) {
- $tmpFile = \OC\Files\Filesystem::toTmpFile($file);
- self::$tmpFiles[] = $tmpFile;
- $zip->addFile($tmpFile, basename($file));
- } elseif (\OC\Files\Filesystem::is_dir($file)) {
- self::zipAddDir($file, $zip);
- }
- }
- $zip->close();
- if ($xsendfile) {
- $filename = OC_Helper::moveToNoClean($filename);
- }
+ $get_type = GET_TYPE::ZIP_FILES;
$basename = basename($dir);
if ($basename) {
$name = $basename . '.zip';
} else {
$name = 'download.zip';
}
-
- set_time_limit($executionTime);
- } elseif (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) {
- self::validateZipDownload($dir, $files);
- $executionTime = intval(ini_get('max_execution_time'));
- set_time_limit(0);
- $zip = new ZipArchive();
- $filename = OC_Helper::tmpFile('.zip');
- if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
- $l = OC_L10N::get('lib');
- throw new Exception($l->t('cannot open "%s"', array($filename)));
- }
- $file = $dir . '/' . $files;
- self::zipAddDir($file, $zip);
- $zip->close();
- if ($xsendfile) {
- $filename = OC_Helper::moveToNoClean($filename);
- }
- // downloading root ?
- if ($files === '') {
- $name = 'download.zip';
+
+ $filename = $dir . '/' . $name;
+ } else {
+ $filename = $dir . '/' . $files;
+ if (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) {
+ $get_type = GET_TYPE::ZIP_DIR;
+ // downloading root ?
+ if ($files === '') {
+ $name = 'download.zip';
+ } else {
+ $name = $files . '.zip';
+ }
+
} else {
- $name = $files . '.zip';
+ $get_type = GET_TYPE::FILE;
+ $name = $files;
}
- set_time_limit($executionTime);
- } else {
+ }
+
+ if ($get_type === GET_TYPE::FILE) {
$zip = false;
- $filename = $dir . '/' . $files;
- $name = $files;
if ($xsendfile && OC_App::isEnabled('files_encryption')) {
$xsendfile = false;
}
+ } else {
+ self::validateZipDownload($dir, $files);
+ $zip = new ZipStreamer(false);
}
OC_Util::obEnd();
if ($zip or \OC\Files\Filesystem::isReadable($filename)) {
- OC_Response::setContentDispositionHeader($name, 'attachment');
- header('Content-Transfer-Encoding: binary');
- OC_Response::disableCaching();
- if ($zip) {
- ini_set('zlib.output_compression', 'off');
- header('Content-Type: application/zip');
- header('Content-Length: ' . filesize($filename));
- self::addSendfileHeader($filename);
- }else{
- $filesize = \OC\Files\Filesystem::filesize($filename);
- header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename));
- if ($filesize > -1) {
- header("Content-Length: ".$filesize);
- }
- if ($xsendfile) {
- list($storage) = \OC\Files\Filesystem::resolvePath(\OC\Files\Filesystem::getView()->getAbsolutePath($filename));
- if ($storage->isLocal()) {
- self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename));
- }
- }
- }
- } elseif ($zip or !\OC\Files\Filesystem::file_exists($filename)) {
+ self::sendHeaders($filename, $name, $zip);
+ } elseif (!\OC\Files\Filesystem::file_exists($filename)) {
header("HTTP/1.0 404 Not Found");
$tmpl = new OC_Template('', '404', 'guest');
$tmpl->assign('file', $name);
@@ -157,23 +127,36 @@ class OC_Files {
return ;
}
if ($zip) {
- $handle = fopen($filename, 'r');
- if ($handle) {
- $chunkSize = 8 * 1024; // 1 MB chunks
- while (!feof($handle)) {
- echo fread($handle, $chunkSize);
- flush();
+ $executionTime = intval(ini_get('max_execution_time'));
+ set_time_limit(0);
+ if ($get_type === GET_TYPE::ZIP_FILES) {
+ foreach ($files as $file) {
+ $file = $dir . '/' . $file;
+ if (\OC\Files\Filesystem::is_file($file)) {
+ $fh = \OC\Files\Filesystem::fopen($file, 'r');
+ $zip->addFileFromStream($fh, basename($file));
+ fclose($fh);
+ } elseif (\OC\Files\Filesystem::is_dir($file)) {
+ self::zipAddDir($file, $zip);
+ }
}
+ } elseif ($get_type === GET_TYPE::ZIP_DIR) {
+ $file = $dir . '/' . $files;
+ self::zipAddDir($file, $zip);
}
- if (!$xsendfile) {
- unlink($filename);
- }
- }else{
- \OC\Files\Filesystem::readfile($filename);
- }
- foreach (self::$tmpFiles as $tmpFile) {
- if (file_exists($tmpFile) and is_file($tmpFile)) {
- unlink($tmpFile);
+ $zip->finalize();
+ set_time_limit($executionTime);
+ } else {
+ if ($xsendfile) {
+ /** @var $storage \OC\Files\Storage\Storage */
+ list($storage) = \OC\Files\Filesystem::resolvePath($filename);
+ if ($storage->isLocal()) {
+ self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename));
+ } else {
+ \OC\Files\Filesystem::readfile($filename);
+ }
+ } else {
+ \OC\Files\Filesystem::readfile($filename);
}
}
}
@@ -186,10 +169,10 @@ class OC_Files {
header("X-Sendfile: " . $filename);
}
if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) {
- if (isset($_SERVER['HTTP_RANGE']) &&
+ if (isset($_SERVER['HTTP_RANGE']) &&
preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) {
$filelength = filesize($filename);
- if ($range[2] == "") {
+ if ($range[2] === "") {
$range[2] = $filelength - 1;
}
header("Content-Range: bytes $range[1]-$range[2]/" . $filelength);
@@ -199,7 +182,7 @@ class OC_Files {
header("X-Sendfile: " . $filename);
}
}
-
+
if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) {
header("X-Accel-Redirect: " . $filename);
}
@@ -207,22 +190,27 @@ class OC_Files {
/**
* @param string $dir
- * @param ZipArchive $zip
+ * @param ZipStreamer $zip
+ * @param string $internalDir
*/
public static function zipAddDir($dir, $zip, $internalDir='') {
$dirname=basename($dir);
- $zip->addEmptyDir($internalDir.$dirname);
+ $rootDir = $internalDir.$dirname;
+ if (!empty($rootDir)) {
+ $zip->addEmptyDir($rootDir);
+ }
$internalDir.=$dirname.='/';
// prevent absolute dirs
$internalDir = ltrim($internalDir, '/');
- $files=OC_Files::getDirectoryContent($dir);
+
+ $files=\OC\Files\Filesystem::getDirectoryContent($dir);
foreach($files as $file) {
$filename=$file['name'];
$file=$dir.'/'.$filename;
if(\OC\Files\Filesystem::is_file($file)) {
- $tmpFile=\OC\Files\Filesystem::toTmpFile($file);
- OC_Files::$tmpFiles[]=$tmpFile;
- $zip->addFile($tmpFile, $internalDir.$filename);
+ $fh = \OC\Files\Filesystem::fopen($file, 'r');
+ $zip->addFileFromStream($fh, $internalDir.$filename);
+ fclose($fh);
}elseif(\OC\Files\Filesystem::is_dir($file)) {
self::zipAddDir($file, $zip, $internalDir);
}
@@ -232,8 +220,8 @@ class OC_Files {
/**
* checks if the selected files are within the size constraint. If not, outputs an error page.
*
- * @param string $dir
- * @param files $files
+ * @param string $dir
+ * @param array | string $files
*/
static function validateZipDownload($dir, $files) {
if (!OC_Config::getValue('allowZipDownload', true)) {
@@ -280,8 +268,8 @@ class OC_Files {
/**
* set the maximum upload size limit for apache hosts using .htaccess
*
- * @param int size filesisze in bytes
- * @return false on failure, size on success
+ * @param int $size file size in bytes
+ * @return bool false on failure, size on success
*/
static function setUploadLimit($size) {
//don't allow user to break his config -- upper boundary
@@ -297,11 +285,12 @@ class OC_Files {
}
//don't allow user to break his config -- broken or malicious size input
- if (intval($size) == 0) {
+ if (intval($size) === 0) {
return false;
}
- $htaccess = @file_get_contents(OC::$SERVERROOT . '/.htaccess'); //supress errors in case we don't have permissions for
+ //suppress errors in case we don't have permissions for
+ $htaccess = @file_get_contents(OC::$SERVERROOT . '/.htaccess');
if (!$htaccess) {
return false;
}
@@ -319,7 +308,7 @@ class OC_Files {
if ($content !== null) {
$htaccess = $content;
}
- if ($hasReplaced == 0) {
+ if ($hasReplaced === 0) {
$htaccess .= "\n" . $setting;
}
}
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index 4cab4619149..9b18257088c 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -166,6 +166,16 @@ class Cache {
*/
public function getFolderContents($folder) {
$fileId = $this->getId($folder);
+ return $this->getFolderContentsById($fileId);
+ }
+
+ /**
+ * get the metadata of all files stored in $folder
+ *
+ * @param int $fileId the file id of the folder
+ * @return array
+ */
+ public function getFolderContentsById($fileId) {
if ($fileId > -1) {
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
`storage_mtime`, `encrypted`, `unencrypted_size`, `etag`
diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php
index a35e4d5e1b9..82f31d0867d 100644
--- a/lib/private/files/cache/homecache.php
+++ b/lib/private/files/cache/homecache.php
@@ -24,15 +24,20 @@ class HomeCache extends Cache {
$entry = $this->get($path);
if ($entry && $entry['mimetype'] === 'httpd/unix-directory') {
$id = $entry['fileid'];
- $sql = 'SELECT SUM(`size`) FROM `*PREFIX*filecache` ' .
+ $sql = 'SELECT SUM(`size`) AS f1, ' .
+ 'SUM(`unencrypted_size`) AS f2 FROM `*PREFIX*filecache` ' .
'WHERE `parent` = ? AND `storage` = ? AND `size` >= 0';
$result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId()));
if ($row = $result->fetchRow()) {
- list($sum) = array_values($row);
+ list($sum, $unencryptedSum) = array_values($row);
$totalSize = (int)$sum;
+ $unencryptedSize = (int)$unencryptedSum;
if ($entry['size'] !== $totalSize) {
$this->update($id, array('size' => $totalSize));
}
+ if ($entry['unencrypted_size'] !== $unencryptedSize) {
+ $this->update($id, array('unencrypted_size' => $unencryptedSize));
+ }
}
}
return $totalSize;
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
index 2dbdd80a26b..d6940f50bf1 100644
--- a/lib/private/files/fileinfo.php
+++ b/lib/private/files/fileinfo.php
@@ -53,7 +53,13 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
}
public function offsetGet($offset) {
- return $this->data[$offset];
+ if ($offset === 'type') {
+ return $this->getType();
+ } elseif (isset($this->data[$offset])) {
+ return $this->data[$offset];
+ } else {
+ return null;
+ }
}
/**
@@ -144,10 +150,14 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
* @return \OCP\Files\FileInfo::TYPE_FILE | \OCP\Files\FileInfo::TYPE_FOLDER
*/
public function getType() {
- return $this->data['type'];
+ if (isset($this->data['type'])) {
+ return $this->data['type'];
+ } else {
+ return $this->getMimetype() === 'httpd/unix-directory' ? self::TYPE_FOLDER : self::TYPE_FILE;
+ }
}
- public function getData(){
+ public function getData() {
return $this->data;
}
diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php
index 952f9f9febf..6478854eae8 100644
--- a/lib/private/files/filesystem.php
+++ b/lib/private/files/filesystem.php
@@ -320,7 +320,8 @@ class Filesystem {
else {
self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user);
}
- $mount_file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
+ $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
+ $mount_file = \OC_Config::getValue("mount_file", $datadir . "/mount.json");
//move config file to it's new position
if (is_file(\OC::$SERVERROOT . '/config/mount.json')) {
@@ -760,7 +761,7 @@ class Filesystem {
*
* @param string $directory path under datadirectory
* @param string $mimetype_filter limit returned content to this mimetype or mimepart
- * @return array
+ * @return \OC\Files\FileInfo[]
*/
public static function getDirectoryContent($directory, $mimetype_filter = '') {
return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter);
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 9e826dd6192..3c078d7b1b4 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -27,6 +27,11 @@ abstract class Common implements \OC\Files\Storage\Storage {
protected $watcher;
protected $storageCache;
+ /**
+ * @var string[]
+ */
+ protected $cachedFiles = array();
+
public function __construct($parameters) {
}
@@ -122,11 +127,13 @@ abstract class Common implements \OC\Files\Storage\Storage {
public function file_put_contents($path, $data) {
$handle = $this->fopen($path, "w");
+ $this->removeCachedFile($path);
return fwrite($handle, $data);
}
public function rename($path1, $path2) {
if ($this->copy($path1, $path2)) {
+ $this->removeCachedFile($path1);
return $this->unlink($path1);
} else {
return false;
@@ -137,6 +144,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
$source = $this->fopen($path1, 'r');
$target = $this->fopen($path2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
+ $this->removeCachedFile($path2);
return $result;
}
@@ -162,13 +170,14 @@ abstract class Common implements \OC\Files\Storage\Storage {
}
public function getLocalFile($path) {
- return $this->toTmpFile($path);
+ return $this->getCachedFile($path);
}
/**
* @param string $path
+ * @return string
*/
- private function toTmpFile($path) { //no longer in the storage api, still useful here
+ protected function toTmpFile($path) { //no longer in the storage api, still useful here
$source = $this->fopen($path, 'r');
if (!$source) {
return false;
@@ -352,4 +361,15 @@ abstract class Common implements \OC\Files\Storage\Storage {
// default, which is not local
return false;
}
+
+ protected function getCachedFile($path) {
+ if (!isset($this->cachedFiles[$path])) {
+ $this->cachedFiles[$path] = $this->toTmpFile($path);
+ }
+ return $this->cachedFiles[$path];
+ }
+
+ protected function removeCachedFile($path) {
+ unset($this->cachedFiles[$path]);
+ }
}
diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index 26c952e694a..ea612735477 100644
--- a/lib/private/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
@@ -36,6 +36,11 @@ class Quota extends Wrapper {
$cache = $this->getCache();
$data = $cache->get($path);
if (is_array($data) and isset($data['size'])) {
+ if (isset($data['unencrypted_size'])
+ && $data['unencrypted_size'] > 0
+ ) {
+ return $data['unencrypted_size'];
+ }
return $data['size'];
} else {
return \OC\Files\SPACE_NOT_COMPUTED;
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 6f235be8e34..2dbbf5b88c9 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -882,12 +882,13 @@ class View {
$watcher->checkUpdate($internalPath);
}
+ $folderId = $cache->getId($internalPath);
$files = array();
- $contents = $cache->getFolderContents($internalPath); //TODO: mimetype_filter
+ $contents = $cache->getFolderContents($internalPath, $folderId); //TODO: mimetype_filter
foreach ($contents as $content) {
$files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content);
}
- $permissions = $permissionsCache->getDirectoryPermissions($cache->getId($internalPath), $user);
+ $permissions = $permissionsCache->getDirectoryPermissions($folderId, $user);
$ids = array();
foreach ($files as $i => $file) {
diff --git a/lib/private/helper.php b/lib/private/helper.php
index 1aab2f296e1..b9956d5ec1c 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -64,7 +64,7 @@ class OC_Helper {
*/
public static function linkToDocs($key) {
$theme = new OC_Defaults();
- return $theme->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key;
+ return $theme->buildDocLinkToKey($key);
}
/**
@@ -839,7 +839,7 @@ class OC_Helper {
* @return int number of bytes representing
*/
public static function maxUploadFilesize($dir, $freeSpace = null) {
- if (is_null($freeSpace)){
+ if (is_null($freeSpace) || $freeSpace < 0){
$freeSpace = self::freeSpace($dir);
}
return min($freeSpace, self::uploadLimit());
diff --git a/lib/private/image.php b/lib/private/image.php
index 17caaa012f5..a4a23f0f097 100644
--- a/lib/private/image.php
+++ b/lib/private/image.php
@@ -41,8 +41,7 @@ class OC_Image {
// exif_imagetype throws "read error!" if file is less than 12 byte
if (filesize($filePath) > 11) {
$imageType = exif_imagetype($filePath);
- }
- else {
+ } else {
$imageType = false;
}
return $imageType ? image_type_to_mime_type($imageType) : '';
@@ -50,7 +49,7 @@ class OC_Image {
/**
* @brief Constructor.
- * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
+ * @param string|resource $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
* @returns bool False on error
*/
public function __construct($imageRef = null) {
@@ -115,13 +114,11 @@ class OC_Image {
case 3:
case 4: // Not tested
return $this->width();
- break;
case 5: // Not tested
case 6:
case 7: // Not tested
case 8:
return $this->height();
- break;
}
return $this->width();
}
@@ -140,13 +137,11 @@ class OC_Image {
case 3:
case 4: // Not tested
return $this->height();
- break;
case 5: // Not tested
case 6:
case 7: // Not tested
case 8:
return $this->width();
- break;
}
return $this->height();
}
@@ -197,7 +192,6 @@ class OC_Image {
return false;
}
- $retVal = false;
switch($this->imageType) {
case IMAGETYPE_GIF:
$retVal = imagegif($this->resource, $filePath);
@@ -264,8 +258,8 @@ class OC_Image {
}
/**
- * @returns Returns a base64 encoded string suitable for embedding in a VCard.
- */
+ * @return string - base64 encoded, which is suitable for embedding in a VCard.
+ */
function __toString() {
return base64_encode($this->data());
}
@@ -307,47 +301,37 @@ class OC_Image {
$o = $this->getOrientation();
OC_Log::write('core', 'OC_Image->fixOrientation() Orientation: '.$o, OC_Log::DEBUG);
$rotate = 0;
- $flip = false;
switch($o) {
case -1:
return false; //Nothing to fix
- break;
case 1:
$rotate = 0;
- $flip = false;
break;
case 2: // Not tested
$rotate = 0;
- $flip = true;
break;
case 3:
$rotate = 180;
- $flip = false;
break;
case 4: // Not tested
$rotate = 180;
- $flip = true;
break;
case 5: // Not tested
$rotate = 90;
- $flip = true;
break;
case 6:
//$rotate = 90;
$rotate = 270;
- $flip = false;
break;
case 7: // Not tested
$rotate = 270;
- $flip = true;
break;
case 8:
$rotate = 90;
- $flip = false;
break;
}
if($rotate) {
- $res = imagerotate($this->resource, $rotate, -1);
+ $res = imagerotate($this->resource, $rotate, 0);
if($res) {
if(imagealphablending($res, true)) {
if(imagesavealpha($res, true)) {
@@ -367,6 +351,7 @@ class OC_Image {
return false;
}
}
+ return false;
}
/**
@@ -382,10 +367,10 @@ class OC_Image {
} elseif(in_array(get_resource_type($imageRef), array('file', 'stream'))) {
return $this->loadFromFileHandle($imageRef);
}
- } elseif($this->loadFromFile($imageRef) !== false) {
- return $this->resource;
} elseif($this->loadFromBase64($imageRef) !== false) {
return $this->resource;
+ } elseif($this->loadFromFile($imageRef) !== false) {
+ return $this->resource;
} elseif($this->loadFromData($imageRef) !== false) {
return $this->resource;
} else {
@@ -416,7 +401,6 @@ class OC_Image {
public function loadFromFile($imagePath=false) {
// exif_imagetype throws "read error!" if file is less than 12 byte
if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
- // Debug output disabled because this method is tried before loadFromBase64?
OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) urlencode($imagePath), OC_Log::DEBUG);
return false;
}
@@ -599,9 +583,9 @@ class OC_Image {
$meta['imagesize'] = $meta['filesize'] - $meta['offset'];
// in rare cases filesize is equal to offset so we need to read physical size
if ($meta['imagesize'] < 1) {
- $meta['imagesize'] = @filesize($filename) - $meta['offset'];
+ $meta['imagesize'] = @filesize($fileName) - $meta['offset'];
if ($meta['imagesize'] < 1) {
- trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING);
+ trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $fileName . '!', E_USER_WARNING);
return false;
}
}
@@ -947,7 +931,7 @@ if ( ! function_exists( 'imagebmp') ) {
$index = imagecolorat($im, $i, $j);
if ($index !== $lastIndex || $sameNum > 255) {
if ($sameNum != 0) {
- $bmpData .= chr($same_num) . chr($lastIndex);
+ $bmpData .= chr($sameNum) . chr($lastIndex);
}
$lastIndex = $index;
$sameNum = 1;
diff --git a/lib/private/installer.php b/lib/private/installer.php
index 11633a4d4a1..64e8e3a5e7a 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -464,7 +464,7 @@ class OC_Installer{
// is the code checker enabled?
if(OC_Config::getValue('appcodechecker', true)) {
// check if grep is installed
- $grep = exec('which grep');
+ $grep = exec('command -v grep');
if($grep=='') {
OC_Log::write('core',
'grep not installed. So checking the code of the app "'.$appname.'" was not possible',
diff --git a/lib/private/l10n.php b/lib/private/l10n.php
index ad979a92870..197b2d6791b 100644
--- a/lib/private/l10n.php
+++ b/lib/private/l10n.php
@@ -73,8 +73,8 @@ class OC_L10N implements \OCP\IL10N {
/**
* get an L10N instance
- * @param $app string
- * @param $lang string|null
+ * @param string $app
+ * @param string|null $lang
* @return OC_L10N
*/
public static function get($app, $lang=null) {
@@ -87,8 +87,8 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief The constructor
- * @param $app string app requesting l10n
- * @param $lang string default: null Language
+ * @param string $app app requesting l10n
+ * @param string $lang default: null Language
* @returns OC_L10N-Object
*
* If language is not set, the constructor tries to find the right
@@ -237,7 +237,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief Translating
- * @param $text String The text we need a translation for
+ * @param string $text The text we need a translation for
* @param array $parameters default:array() Parameters for sprintf
* @return \OC_L10N_String Translation or the same text
*
@@ -250,9 +250,9 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief Translating
- * @param $text_singular String the string to translate for exactly one object
- * @param $text_plural String the string to translate for n objects
- * @param $count Integer Number of objects
+ * @param string $text_singular the string to translate for exactly one object
+ * @param string $text_plural the string to translate for n objects
+ * @param integer $count Number of objects
* @param array $parameters default:array() Parameters for sprintf
* @return \OC_L10N_String Translation or the same text
*
@@ -351,7 +351,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief Localization
- * @param $type Type of localization
+ * @param string $type Type of localization
* @param $params parameters for this localization
* @returns String or false
*
@@ -406,7 +406,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief Choose a language
- * @param $texts Associative Array with possible strings
+ * @param array $text Associative Array with possible strings
* @returns String
*
* $text is an array 'de' => 'hallo welt', 'en' => 'hello world', ...
@@ -421,7 +421,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief find the best language
- * @param $app Array or string, details below
+ * @param array|string $app details below
* @returns string language
*
* If $app is an array, ownCloud assumes that these are the available
@@ -494,7 +494,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief find the l10n directory
- * @param $app App that needs to be translated
+ * @param string $app App that needs to be translated
* @returns directory
*/
protected static function findI18nDir($app) {
@@ -514,7 +514,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief find all available languages for an app
- * @param $app App that needs to be translated
+ * @param string $app App that needs to be translated
* @returns array an array of available languages
*/
public static function findAvailableLanguages($app=null) {
@@ -533,7 +533,9 @@ class OC_L10N implements \OCP\IL10N {
}
/**
+ * @param string $app
* @param string $lang
+ * @returns bool
*/
public static function languageExists($app, $lang) {
if ($lang == 'en') {//english is always available
diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php
index 9bd07b89023..a216414c9dd 100644
--- a/lib/private/mimetypes.list.php
+++ b/lib/private/mimetypes.list.php
@@ -31,6 +31,7 @@ return array(
'bash' => 'text/x-shellscript',
'blend' => 'application/x-blender',
'bin' => 'application/x-bin',
+ 'bmp' => 'image/bmp',
'cb7' => 'application/x-cbr',
'cba' => 'application/x-cbr',
'cbr' => 'application/x-cbr',
diff --git a/lib/private/ocs/cloud.php b/lib/private/ocs/cloud.php
index cbbf3b626f5..06d6a8eb4b0 100644
--- a/lib/private/ocs/cloud.php
+++ b/lib/private/ocs/cloud.php
@@ -61,17 +61,29 @@ class OC_OCS_Cloud {
* the user from whom the information will be returned
*/
public static function getUser($parameters) {
+ $return = array();
// Check if they are viewing information on themselves
if($parameters['userid'] === OC_User::getUser()) {
// Self lookup
$storage = OC_Helper::getStorageInfo('/');
- $quota = array(
+ $return['quota'] = array(
'free' => $storage['free'],
'used' => $storage['used'],
'total' => $storage['total'],
'relative' => $storage['relative'],
);
- return new OC_OCS_Result(array('quota' => $quota));
+ }
+ if(OC_User::isAdminUser(OC_User::getUser())
+ || OC_Subadmin::isUserAccessible(OC_User::getUser(), $parameters['userid'])) {
+ if(OC_User::userExists($parameters['userid'])) {
+ // Is an admin/subadmin so can see display name
+ $return['displayname'] = OC_User::getDisplayName($parameters['userid']);
+ } else {
+ return new OC_OCS_Result(null, 101);
+ }
+ }
+ if(count($return)) {
+ return new OC_OCS_Result($return);
} else {
// No permission to view this user data
return new OC_OCS_Result(null, 997);
diff --git a/lib/private/preview.php b/lib/private/preview.php
index 80fd003ed8d..74051fbc2a3 100755
--- a/lib/private/preview.php
+++ b/lib/private/preview.php
@@ -53,6 +53,11 @@ class Preview {
static private $registeredProviders = array();
/**
+ * @var \OCP\Files\FileInfo
+ */
+ protected $info;
+
+ /**
* @brief check if thumbnail or bigger version of thumbnail of file is cached
* @param string $user userid - if no user is given, OC_User::getUser will be used
* @param string $root path of root
@@ -61,12 +66,12 @@ class Preview {
* @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
* @param bool $scalingUp Disable/Enable upscaling of previews
* @return mixed (bool / string)
- * false if thumbnail does not exist
- * path to thumbnail if thumbnail exists
- */
- public function __construct($user='', $root='/', $file='', $maxX=1, $maxY=1, $scalingUp=true) {
+ * false if thumbnail does not exist
+ * path to thumbnail if thumbnail exists
+ */
+ public function __construct($user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true) {
//init fileviews
- if($user === ''){
+ if ($user === '') {
$user = \OC_User::getUser();
}
$this->fileView = new \OC\Files\View('/' . $user . '/' . $root);
@@ -86,11 +91,11 @@ class Preview {
$this->preview = null;
//check if there are preview backends
- if(empty(self::$providers)) {
+ if (empty(self::$providers)) {
self::initProviders();
}
- if(empty(self::$providers)) {
+ if (empty(self::$providers)) {
\OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR);
throw new \Exception('No preview providers');
}
@@ -99,15 +104,15 @@ class Preview {
/**
* @brief returns the path of the file you want a thumbnail from
* @return string
- */
- public function getFile() {
+ */
+ public function getFile() {
return $this->file;
}
/**
* @brief returns the max width of the preview
* @return integer
- */
+ */
public function getMaxX() {
return $this->maxX;
}
@@ -115,7 +120,7 @@ class Preview {
/**
* @brief returns the max height of the preview
* @return integer
- */
+ */
public function getMaxY() {
return $this->maxY;
}
@@ -123,7 +128,7 @@ class Preview {
/**
* @brief returns whether or not scalingup is enabled
* @return bool
- */
+ */
public function getScalingUp() {
return $this->scalingup;
}
@@ -131,7 +136,7 @@ class Preview {
/**
* @brief returns the name of the thumbnailfolder
* @return string
- */
+ */
public function getThumbnailsFolder() {
return self::THUMBNAILS_FOLDER;
}
@@ -139,7 +144,7 @@ class Preview {
/**
* @brief returns the max scale factor
* @return string
- */
+ */
public function getMaxScaleFactor() {
return $this->maxScaleFactor;
}
@@ -147,7 +152,7 @@ class Preview {
/**
* @brief returns the max width set in ownCloud's config
* @return string
- */
+ */
public function getConfigMaxX() {
return $this->configMaxX;
}
@@ -155,20 +160,28 @@ class Preview {
/**
* @brief returns the max height set in ownCloud's config
* @return string
- */
+ */
public function getConfigMaxY() {
return $this->configMaxY;
}
+ protected function getFileInfo() {
+ if (!$this->info) {
+ $this->info = $this->fileView->getFileInfo($this->file);
+ }
+ return $this->info;
+ }
+
/**
* @brief set the path of the file you want a thumbnail from
* @param string $file
* @return $this
- */
+ */
public function setFile($file) {
$this->file = $file;
+ $this->info = null;
if ($file !== '') {
- $this->mimetype = $this->fileView->getMimeType($this->file);
+ $this->mimetype = $this->getFileInfo()->getMimetype();
}
return $this;
}
@@ -185,14 +198,14 @@ class Preview {
* @brief set the the max width of the preview
* @param int $maxX
* @return $this
- */
- public function setMaxX($maxX=1) {
- if($maxX <= 0) {
+ */
+ public function setMaxX($maxX = 1) {
+ if ($maxX <= 0) {
throw new \Exception('Cannot set width of 0 or smaller!');
}
$configMaxX = $this->getConfigMaxX();
- if(!is_null($configMaxX)) {
- if($maxX > $configMaxX) {
+ if (!is_null($configMaxX)) {
+ if ($maxX > $configMaxX) {
\OC_Log::write('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OC_Log::DEBUG);
$maxX = $configMaxX;
}
@@ -205,14 +218,14 @@ class Preview {
* @brief set the the max height of the preview
* @param int $maxY
* @return $this
- */
- public function setMaxY($maxY=1) {
- if($maxY <= 0) {
+ */
+ public function setMaxY($maxY = 1) {
+ if ($maxY <= 0) {
throw new \Exception('Cannot set height of 0 or smaller!');
}
$configMaxY = $this->getConfigMaxY();
- if(!is_null($configMaxY)) {
- if($maxY > $configMaxY) {
+ if (!is_null($configMaxY)) {
+ if ($maxY > $configMaxY) {
\OC_Log::write('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OC_Log::DEBUG);
$maxY = $configMaxY;
}
@@ -225,9 +238,9 @@ class Preview {
* @brief set whether or not scalingup is enabled
* @param bool $scalingUp
* @return $this
- */
+ */
public function setScalingup($scalingUp) {
- if($this->getMaxScaleFactor() === 1) {
+ if ($this->getMaxScaleFactor() === 1) {
$scalingUp = false;
}
$this->scalingup = $scalingUp;
@@ -237,15 +250,15 @@ class Preview {
/**
* @brief check if all parameters are valid
* @return bool
- */
+ */
public function isFileValid() {
$file = $this->getFile();
- if($file === '') {
+ if ($file === '') {
\OC_Log::write('core', 'No filename passed', \OC_Log::DEBUG);
return false;
}
- if(!$this->fileView->file_exists($file)) {
+ if (!$this->fileView->file_exists($file)) {
\OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::DEBUG);
return false;
}
@@ -256,40 +269,38 @@ class Preview {
/**
* @brief deletes previews of a file with specific x and y
* @return bool
- */
+ */
public function deletePreview() {
$file = $this->getFile();
- $fileInfo = $this->fileView->getFileInfo($file);
- $fileId = $fileInfo['fileid'];
+ $fileInfo = $this->getFileInfo($file);
+ $fileId = $fileInfo->getId();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png';
- $this->userView->unlink($previewPath);
- return !$this->userView->file_exists($previewPath);
+ return $this->userView->unlink($previewPath);
}
/**
* @brief deletes all previews of a file
* @return bool
- */
+ */
public function deleteAllPreviews() {
$file = $this->getFile();
- $fileInfo = $this->fileView->getFileInfo($file);
- $fileId = $fileInfo['fileid'];
+ $fileInfo = $this->getFileInfo($file);
+ $fileId = $fileInfo->getId();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$this->userView->deleteAll($previewPath);
- $this->userView->rmdir($previewPath);
- return !$this->userView->is_dir($previewPath);
+ return $this->userView->rmdir($previewPath);
}
/**
* @brief check if thumbnail or bigger version of thumbnail of file is cached
* @return mixed (bool / string)
- * false if thumbnail does not exist
- * path to thumbnail if thumbnail exists
- */
+ * false if thumbnail does not exist
+ * path to thumbnail if thumbnail exists
+ */
private function isCached() {
$file = $this->getFile();
$maxX = $this->getMaxX();
@@ -297,75 +308,75 @@ class Preview {
$scalingUp = $this->getScalingUp();
$maxScaleFactor = $this->getMaxScaleFactor();
- $fileInfo = $this->fileView->getFileInfo($file);
- $fileId = $fileInfo['fileid'];
+ $fileInfo = $this->getFileInfo($file);
+ $fileId = $fileInfo->getId();
- if(is_null($fileId)) {
+ if (is_null($fileId)) {
return false;
}
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
- if(!$this->userView->is_dir($previewPath)) {
+ if (!$this->userView->is_dir($previewPath)) {
return false;
}
//does a preview with the wanted height and width already exist?
- if($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) {
+ if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) {
return $previewPath . $maxX . '-' . $maxY . '.png';
}
- $wantedAspectRatio = (float) ($maxX / $maxY);
+ $wantedAspectRatio = (float)($maxX / $maxY);
//array for usable cached thumbnails
$possibleThumbnails = array();
$allThumbnails = $this->userView->getDirectoryContent($previewPath);
- foreach($allThumbnails as $thumbnail) {
+ foreach ($allThumbnails as $thumbnail) {
$name = rtrim($thumbnail['name'], '.png');
$size = explode('-', $name);
- $x = (int) $size[0];
- $y = (int) $size[1];
+ $x = (int)$size[0];
+ $y = (int)$size[1];
- $aspectRatio = (float) ($x / $y);
- if($aspectRatio !== $wantedAspectRatio) {
+ $aspectRatio = (float)($x / $y);
+ if ($aspectRatio !== $wantedAspectRatio) {
continue;
}
- if($x < $maxX || $y < $maxY) {
- if($scalingUp) {
+ if ($x < $maxX || $y < $maxY) {
+ if ($scalingUp) {
$scalefactor = $maxX / $x;
- if($scalefactor > $maxScaleFactor) {
+ if ($scalefactor > $maxScaleFactor) {
continue;
}
- }else{
+ } else {
continue;
}
}
$possibleThumbnails[$x] = $thumbnail['path'];
}
- if(count($possibleThumbnails) === 0) {
+ if (count($possibleThumbnails) === 0) {
return false;
}
- if(count($possibleThumbnails) === 1) {
+ if (count($possibleThumbnails) === 1) {
return current($possibleThumbnails);
}
ksort($possibleThumbnails);
- if(key(reset($possibleThumbnails)) > $maxX) {
+ if (key(reset($possibleThumbnails)) > $maxX) {
return current(reset($possibleThumbnails));
}
- if(key(end($possibleThumbnails)) < $maxX) {
+ if (key(end($possibleThumbnails)) < $maxX) {
return current(end($possibleThumbnails));
}
- foreach($possibleThumbnails as $width => $path) {
- if($width < $maxX) {
+ foreach ($possibleThumbnails as $width => $path) {
+ if ($width < $maxX) {
continue;
- }else{
+ } else {
return $path;
}
}
@@ -374,9 +385,9 @@ class Preview {
/**
* @brief return a preview of a file
* @return \OC_Image
- */
+ */
public function getPreview() {
- if(!is_null($this->preview) && $this->preview->valid()){
+ if (!is_null($this->preview) && $this->preview->valid()) {
return $this->preview;
}
@@ -386,22 +397,25 @@ class Preview {
$maxY = $this->getMaxY();
$scalingUp = $this->getScalingUp();
- $fileInfo = $this->fileView->getFileInfo($file);
- $fileId = $fileInfo['fileid'];
+ $fileInfo = $this->getFileInfo($file);
+ $fileId = $fileInfo->getId();
$cached = $this->isCached();
- if($cached) {
- $image = new \OC_Image($this->userView->file_get_contents($cached, 'r'));
+ if ($cached) {
+ $stream = $this->userView->fopen($cached, 'r');
+ $image = new \OC_Image();
+ $image->loadFromFileHandle($stream);
$this->preview = $image->valid() ? $image : null;
$this->resizeAndCrop();
+ fclose($stream);
}
- if(is_null($this->preview)) {
+ if (is_null($this->preview)) {
$preview = null;
- foreach(self::$providers as $supportedMimetype => $provider) {
- if(!preg_match($supportedMimetype, $this->mimetype)) {
+ foreach (self::$providers as $supportedMimetype => $provider) {
+ if (!preg_match($supportedMimetype, $this->mimetype)) {
continue;
}
@@ -409,7 +423,7 @@ class Preview {
$preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView);
- if(!($preview instanceof \OC_Image)) {
+ if (!($preview instanceof \OC_Image)) {
continue;
}
@@ -419,11 +433,11 @@ class Preview {
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$cachePath = $previewPath . $maxX . '-' . $maxY . '.png';
- if($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) {
+ if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) {
$this->userView->mkdir($this->getThumbnailsFolder() . '/');
}
- if($this->userView->is_dir($previewPath) === false) {
+ if ($this->userView->is_dir($previewPath) === false) {
$this->userView->mkdir($previewPath);
}
@@ -433,7 +447,7 @@ class Preview {
}
}
- if(is_null($this->preview)) {
+ if (is_null($this->preview)) {
$this->preview = new \OC_Image();
}
@@ -443,10 +457,10 @@ class Preview {
/**
* @brief show preview
* @return void
- */
+ */
public function showPreview() {
\OCP\Response::enableCaching(3600 * 24); // 24 hours
- if(is_null($this->preview)) {
+ if (is_null($this->preview)) {
$this->getPreview();
}
$this->preview->show();
@@ -456,7 +470,7 @@ class Preview {
/**
* @brief show preview
* @return void
- */
+ */
public function show() {
$this->showPreview();
return;
@@ -465,7 +479,7 @@ class Preview {
/**
* @brief resize, crop and fix orientation
* @return void
- */
+ */
private function resizeAndCrop() {
$image = $this->preview;
$x = $this->getMaxX();
@@ -473,17 +487,17 @@ class Preview {
$scalingUp = $this->getScalingUp();
$maxscalefactor = $this->getMaxScaleFactor();
- if(!($image instanceof \OC_Image)) {
+ if (!($image instanceof \OC_Image)) {
\OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG);
return;
}
$image->fixOrientation();
- $realx = (int) $image->width();
- $realy = (int) $image->height();
+ $realx = (int)$image->width();
+ $realy = (int)$image->height();
- if($x === $realx && $y === $realy) {
+ if ($x === $realx && $y === $realy) {
$this->preview = $image;
return;
}
@@ -491,36 +505,36 @@ class Preview {
$factorX = $x / $realx;
$factorY = $y / $realy;
- if($factorX >= $factorY) {
+ if ($factorX >= $factorY) {
$factor = $factorX;
- }else{
+ } else {
$factor = $factorY;
}
- if($scalingUp === false) {
- if($factor > 1) {
+ if ($scalingUp === false) {
+ if ($factor > 1) {
$factor = 1;
}
}
- if(!is_null($maxscalefactor)) {
- if($factor > $maxscalefactor) {
+ if (!is_null($maxscalefactor)) {
+ if ($factor > $maxscalefactor) {
\OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG);
$factor = $maxscalefactor;
}
}
- $newXsize = (int) ($realx * $factor);
- $newYsize = (int) ($realy * $factor);
+ $newXsize = (int)($realx * $factor);
+ $newYsize = (int)($realy * $factor);
$image->preciseResize($newXsize, $newYsize);
- if($newXsize === $x && $newYsize === $y) {
+ if ($newXsize === $x && $newYsize === $y) {
$this->preview = $image;
return;
}
- if($newXsize >= $x && $newYsize >= $y) {
+ if ($newXsize >= $x && $newYsize >= $y) {
$cropX = floor(abs($x - $newXsize) * 0.5);
//don't crop previews on the Y axis, this sucks if it's a document.
//$cropY = floor(abs($y - $newYsize) * 0.5);
@@ -532,19 +546,19 @@ class Preview {
return;
}
- if($newXsize < $x || $newYsize < $y) {
- if($newXsize > $x) {
+ if ($newXsize < $x || $newYsize < $y) {
+ if ($newXsize > $x) {
$cropX = floor(($newXsize - $x) * 0.5);
$image->crop($cropX, 0, $x, $newYsize);
}
- if($newYsize > $y) {
+ if ($newYsize > $y) {
$cropY = floor(($newYsize - $y) * 0.5);
$image->crop(0, $cropY, $newXsize, $y);
}
- $newXsize = (int) $image->width();
- $newYsize = (int) $image->height();
+ $newXsize = (int)$image->width();
+ $newYsize = (int)$image->height();
//create transparent background layer
$backgroundlayer = imagecreatetruecolor($x, $y);
@@ -573,8 +587,8 @@ class Preview {
* @param array $options
* @return void
*/
- public static function registerProvider($class, $options=array()) {
- self::$registeredProviders[]=array('class'=>$class, 'options'=>$options);
+ public static function registerProvider($class, $options = array()) {
+ self::$registeredProviders[] = array('class' => $class, 'options' => $options);
}
/**
@@ -582,19 +596,19 @@ class Preview {
* @return void
*/
private static function initProviders() {
- if(!\OC_Config::getValue('enable_previews', true)) {
+ if (!\OC_Config::getValue('enable_previews', true)) {
$provider = new Preview\Unknown(array());
self::$providers = array($provider->getMimeType() => $provider);
return;
}
- if(count(self::$providers)>0) {
+ if (count(self::$providers) > 0) {
return;
}
- foreach(self::$registeredProviders as $provider) {
- $class=$provider['class'];
- $options=$provider['options'];
+ foreach (self::$registeredProviders as $provider) {
+ $class = $provider['class'];
+ $options = $provider['options'];
$object = new $class($options);
@@ -611,7 +625,7 @@ class Preview {
public static function post_delete($args) {
$path = $args['path'];
- if(substr($path, 0, 1) === '/') {
+ if (substr($path, 0, 1) === '/') {
$path = substr($path, 1);
}
$preview = new Preview(\OC_User::getUser(), 'files/', $path);
@@ -622,19 +636,19 @@ class Preview {
* @param string $mimetype
*/
public static function isMimeSupported($mimetype) {
- if(!\OC_Config::getValue('enable_previews', true)) {
+ if (!\OC_Config::getValue('enable_previews', true)) {
return false;
}
//check if there are preview backends
- if(empty(self::$providers)) {
+ if (empty(self::$providers)) {
self::initProviders();
}
//remove last element because it has the mimetype *
$providers = array_slice(self::$providers, 0, -1);
- foreach($providers as $supportedMimetype => $provider) {
- if(preg_match($supportedMimetype, $mimetype)) {
+ foreach ($providers as $supportedMimetype => $provider) {
+ if (preg_match($supportedMimetype, $mimetype)) {
return true;
}
}
diff --git a/lib/private/preview/movies.php b/lib/private/preview/movies.php
index 71cd3bae057..7e0ff51ad2e 100644
--- a/lib/private/preview/movies.php
+++ b/lib/private/preview/movies.php
@@ -9,7 +9,7 @@
namespace OC\Preview;
function findBinaryPath($program) {
- exec('which ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode);
+ exec('command -v ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode);
if ($returnCode === 0 && count($output) > 0) {
return escapeshellcmd($output[0]);
}
diff --git a/lib/private/preview/office-cl.php b/lib/private/preview/office-cl.php
index b11fed13ba1..6e4d4321eb7 100644
--- a/lib/private/preview/office-cl.php
+++ b/lib/private/preview/office-cl.php
@@ -64,12 +64,12 @@ if (!\OC_Util::runningOnWindows()) {
$cmd = \OC_Config::getValue('preview_libreoffice_path', null);
}
- $whichLibreOffice = shell_exec('which libreoffice');
+ $whichLibreOffice = shell_exec('command -v libreoffice');
if($cmd === '' && !empty($whichLibreOffice)) {
$cmd = 'libreoffice';
}
- $whichOpenOffice = shell_exec('which openoffice');
+ $whichOpenOffice = shell_exec('command -v openoffice');
if($cmd === '' && !empty($whichOpenOffice)) {
$cmd = 'openoffice';
}
diff --git a/lib/private/preview/office.php b/lib/private/preview/office.php
index 02bb22e9b94..882c4426e6d 100644
--- a/lib/private/preview/office.php
+++ b/lib/private/preview/office.php
@@ -6,24 +6,29 @@
* See the COPYING-README file.
*/
//both, libreoffice backend and php fallback, need imagick
-if (extension_loaded('imagick') && count(@\Imagick::queryFormats("PDF")) === 1) {
- $isShellExecEnabled = \OC_Helper::is_function_enabled('shell_exec');
+if (extension_loaded('imagick')) {
- // LibreOffice preview is currently not supported on Windows
- if (!\OC_Util::runningOnWindows()) {
- $whichLibreOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : '');
- $isLibreOfficeAvailable = !empty($whichLibreOffice);
- $whichOpenOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : '');
- $isOpenOfficeAvailable = !empty($whichOpenOffice);
- //let's see if there is libreoffice or openoffice on this machine
- if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) {
- require_once('office-cl.php');
- }else{
+ $checkImagick = new Imagick();
+
+ if(count($checkImagick->queryFormats('PDF')) === 1) {
+ $isShellExecEnabled = \OC_Helper::is_function_enabled('shell_exec');
+
+ // LibreOffice preview is currently not supported on Windows
+ if (!\OC_Util::runningOnWindows()) {
+ $whichLibreOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
+ $isLibreOfficeAvailable = !empty($whichLibreOffice);
+ $whichOpenOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
+ $isOpenOfficeAvailable = !empty($whichOpenOffice);
+ //let's see if there is libreoffice or openoffice on this machine
+ if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) {
+ require_once('office-cl.php');
+ }else{
+ //in case there isn't, use our fallback
+ require_once('office-fallback.php');
+ }
+ } else {
//in case there isn't, use our fallback
require_once('office-fallback.php');
}
- } else {
- //in case there isn't, use our fallback
- require_once('office-fallback.php');
}
}
diff --git a/lib/private/preview/pdf.php b/lib/private/preview/pdf.php
index d390b4fc677..064a5a3b3d1 100644
--- a/lib/private/preview/pdf.php
+++ b/lib/private/preview/pdf.php
@@ -7,34 +7,41 @@
*/
namespace OC\Preview;
-if (extension_loaded('imagick') && count(@\Imagick::queryFormats("PDF")) === 1) {
+use Imagick;
- class PDF extends Provider {
+if (extension_loaded('imagick')) {
- public function getMimeType() {
- return '/application\/pdf/';
- }
+ $checkImagick = new Imagick();
+
+ if(count($checkImagick->queryFormats('PDF')) === 1) {
- public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
- $tmpPath = $fileview->toTmpFile($path);
+ class PDF extends Provider {
- //create imagick object from pdf
- try{
- $pdf = new \imagick($tmpPath . '[0]');
- $pdf->setImageFormat('jpg');
- } catch (\Exception $e) {
- \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
- return false;
+ public function getMimeType() {
+ return '/application\/pdf/';
}
- unlink($tmpPath);
+ public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
+ $tmpPath = $fileview->toTmpFile($path);
+
+ //create imagick object from pdf
+ try{
+ $pdf = new Imagick($tmpPath . '[0]');
+ $pdf->setImageFormat('jpg');
+ } catch (\Exception $e) {
+ \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
+ return false;
+ }
+
+ unlink($tmpPath);
- //new image object
- $image = new \OC_Image($pdf);
- //check if image object is valid
- return $image->valid() ? $image : false;
+ //new image object
+ $image = new \OC_Image($pdf);
+ //check if image object is valid
+ return $image->valid() ? $image : false;
+ }
}
- }
- \OC\Preview::registerProvider('OC\Preview\PDF');
+ \OC\Preview::registerProvider('OC\Preview\PDF');
+ }
}
diff --git a/lib/private/preview/svg.php b/lib/private/preview/svg.php
index 9a73fff9467..505122fddbf 100644
--- a/lib/private/preview/svg.php
+++ b/lib/private/preview/svg.php
@@ -7,40 +7,46 @@
*/
namespace OC\Preview;
-if (extension_loaded('imagick') && count(@\Imagick::queryFormats("SVG")) === 1) {
+use Imagick;
- class SVG extends Provider {
+if (extension_loaded('imagick')) {
- public function getMimeType() {
- return '/image\/svg\+xml/';
- }
+ $checkImagick = new Imagick();
- public function getThumbnail($path,$maxX,$maxY,$scalingup,$fileview) {
- try{
- $svg = new \Imagick();
- $svg->setBackgroundColor(new \ImagickPixel('transparent'));
+ if(count($checkImagick->queryFormats('SVG')) === 1) {
- $content = stream_get_contents($fileview->fopen($path, 'r'));
- if(substr($content, 0, 5) !== '<?xml') {
- $content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $content;
- }
+ class SVG extends Provider {
- $svg->readImageBlob($content);
- $svg->setImageFormat('png32');
- } catch (\Exception $e) {
- \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
- return false;
+ public function getMimeType() {
+ return '/image\/svg\+xml/';
}
+ public function getThumbnail($path,$maxX,$maxY,$scalingup,$fileview) {
+ try{
+ $svg = new Imagick();
+ $svg->setBackgroundColor(new \ImagickPixel('transparent'));
+
+ $content = stream_get_contents($fileview->fopen($path, 'r'));
+ if(substr($content, 0, 5) !== '<?xml') {
+ $content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $content;
+ }
+
+ $svg->readImageBlob($content);
+ $svg->setImageFormat('png32');
+ } catch (\Exception $e) {
+ \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
+ return false;
+ }
- //new image object
- $image = new \OC_Image();
- $image->loadFromData($svg);
- //check if image object is valid
- return $image->valid() ? $image : false;
- }
- }
- \OC\Preview::registerProvider('OC\Preview\SVG');
+ //new image object
+ $image = new \OC_Image();
+ $image->loadFromData($svg);
+ //check if image object is valid
+ return $image->valid() ? $image : false;
+ }
+ }
+ \OC\Preview::registerProvider('OC\Preview\SVG');
+ }
} \ No newline at end of file
diff --git a/lib/private/request.php b/lib/private/request.php
index afd3fda4f2d..8041c4f0048 100755
--- a/lib/private/request.php
+++ b/lib/private/request.php
@@ -13,6 +13,8 @@ class OC_Request {
const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
+ const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)(:[0-9]+|)$/';
+
/**
* @brief Check overwrite condition
* @param string $type
@@ -25,49 +27,91 @@ class OC_Request {
}
/**
- * @brief Checks whether a domain is considered as trusted. This is used to prevent Host Header Poisoning.
+ * @brief Checks whether a domain is considered as trusted from the list
+ * of trusted domains. If no trusted domains have been configured, returns
+ * true.
+ * This is used to prevent Host Header Poisoning.
* @param string $host
- * @return bool
+ * @return bool true if the given domain is trusted or if no trusted domains
+ * have been configured
*/
public static function isTrustedDomain($domain) {
- $trustedList = \OC_Config::getValue('trusted_domains', array(''));
+ $trustedList = \OC_Config::getValue('trusted_domains', array());
+ if (empty($trustedList)) {
+ return true;
+ }
+ if (preg_match(self::REGEX_LOCALHOST, $domain) === 1) {
+ return true;
+ }
return in_array($domain, $trustedList);
}
/**
- * @brief Returns the server host
+ * @brief Returns the unverified server host from the headers without checking
+ * whether it is a trusted domain
* @returns string the server host
*
* Returns the server host, even if the website uses one or more
* reverse proxies
*/
- public static function serverHost() {
- if(OC::$CLI) {
- return 'localhost';
- }
- if(OC_Config::getValue('overwritehost', '') !== '' and self::isOverwriteCondition()) {
- return OC_Config::getValue('overwritehost');
- }
+ public static function insecureServerHost() {
+ $host = null;
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) {
- $host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST'])));
- }
- else{
+ $parts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
+ $host = trim(current($parts));
+ } else {
$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
} else {
if (isset($_SERVER['HTTP_HOST'])) {
$host = $_SERVER['HTTP_HOST'];
- }
- else if (isset($_SERVER['SERVER_NAME'])) {
+ } else if (isset($_SERVER['SERVER_NAME'])) {
$host = $_SERVER['SERVER_NAME'];
}
}
+ return $host;
+ }
+
+ /**
+ * Returns the overwritehost setting from the config if set and
+ * if the overwrite condition is met
+ * @return overwritehost value or null if not defined or the defined condition
+ * isn't met
+ */
+ public static function getOverwriteHost() {
+ if(OC_Config::getValue('overwritehost', '') !== '' and self::isOverwriteCondition()) {
+ return OC_Config::getValue('overwritehost');
+ }
+ return null;
+ }
+
+ /**
+ * @brief Returns the server host from the headers, or the first configured
+ * trusted domain if the host isn't in the trusted list
+ * @returns string the server host
+ *
+ * Returns the server host, even if the website uses one or more
+ * reverse proxies
+ */
+ public static function serverHost() {
+ if(OC::$CLI) {
+ return 'localhost';
+ }
+
+ // overwritehost is always trusted
+ $host = self::getOverwriteHost();
+ if ($host !== null) {
+ return $host;
+ }
+
+ // get the host from the headers
+ $host = self::insecureServerHost();
// Verify that the host is a trusted domain if the trusted domains
// are defined
// If no trusted domain is provided the first trusted domain is returned
- if(self::isTrustedDomain($host) || \OC_Config::getValue('trusted_domains', "") === "") {
+ if (self::isTrustedDomain($host)) {
return $host;
} else {
$trustedList = \OC_Config::getValue('trusted_domains', array(''));
diff --git a/lib/private/router.php b/lib/private/router.php
index 19c1e4473ec..918e3b13206 100644
--- a/lib/private/router.php
+++ b/lib/private/router.php
@@ -158,28 +158,4 @@ class OC_Router {
return $this->getGenerator()->generate($name, $parameters, $absolute);
}
- /**
- * Generate JSON response for routing in javascript
- */
- public static function JSRoutes()
- {
- $router = OC::getRouter();
-
- $etag = $router->getCacheKey();
- OC_Response::enableCaching();
- OC_Response::setETagHeader($etag);
-
- $root = $router->getCollection('root');
- $routes = array();
- foreach($root->all() as $name => $route) {
- $compiled_route = $route->compile();
- $defaults = $route->getDefaults();
- unset($defaults['action']);
- $routes[$name] = array(
- 'tokens' => $compiled_route->getTokens(),
- 'defaults' => $defaults,
- );
- }
- OCP\JSON::success ( array( 'data' => $routes ) );
- }
}
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 3906204bda3..0d5bf424b33 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -147,7 +147,7 @@ class OC_Setup {
$content.= "RewriteRule ^.well-known/host-meta /public.php?service=host-meta [QSA,L]\n";
$content.= "RewriteRule ^.well-known/carddav /remote.php/carddav/ [R]\n";
$content.= "RewriteRule ^.well-known/caldav /remote.php/caldav/ [R]\n";
- $content.= "RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]\n";
+ $content.= "RewriteRule ^apps/([^/]*)/(.*\.(php))$ index.php?app=$1&getfile=$2 [QSA,L]\n";
$content.= "RewriteRule ^remote/(.*) remote.php [QSA,L]\n";
$content.= "</IfModule>\n";
$content.= "<IfModule mod_mime.c>\n";
diff --git a/lib/private/template/base.php b/lib/private/template/base.php
index 232a29939cc..7aa0cb4a956 100644
--- a/lib/private/template/base.php
+++ b/lib/private/template/base.php
@@ -61,7 +61,7 @@ class Base {
/**
* @brief Assign variables
* @param string $key key
- * @param string $value value
+ * @param array|bool|integer|string $value value
* @return bool
*
* This function assigns a variable. It can be accessed via $_[$key] in
diff --git a/lib/public/files/fileinfo.php b/lib/public/files/fileinfo.php
index 68ce45d3fa1..37162e09336 100644
--- a/lib/public/files/fileinfo.php
+++ b/lib/public/files/fileinfo.php
@@ -9,7 +9,7 @@ namespace OCP\Files;
interface FileInfo {
const TYPE_FILE = 'file';
- const TYPE_FOLDER = 'folder';
+ const TYPE_FOLDER = 'dir';
/**
* Get the Etag of the file or folder
diff --git a/lib/public/share.php b/lib/public/share.php
index ebc555dba5f..2fed41488ca 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -1250,7 +1250,21 @@ class Share {
// Remove root from file source paths if retrieving own shared items
if (isset($uidOwner) && isset($row['path'])) {
if (isset($row['parent'])) {
- $row['path'] = '/Shared/'.basename($row['path']);
+ $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
+ $parentResult = $query->execute(array($row['parent']));
+ if (\OC_DB::isError($result)) {
+ \OC_Log::write('OCP\Share', 'Can\'t select parent: ' .
+ \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
+ \OC_Log::ERROR);
+ } else {
+ $parentRow = $parentResult->fetchRow();
+ $splitPath = explode('/', $row['path']);
+ $tmpPath = '/Shared' . $parentRow['file_target'];
+ foreach (array_slice($splitPath, 2) as $pathPart) {
+ $tmpPath = $tmpPath . '/' . $pathPart;
+ }
+ $row['path'] = $tmpPath;
+ }
} else {
if (!isset($mounts[$row['storage']])) {
$mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
diff --git a/settings/admin.php b/settings/admin.php
index c0e4570658a..42477bfc1ca 100755
--- a/settings/admin.php
+++ b/settings/admin.php
@@ -21,6 +21,16 @@ $entries=OC_Log_Owncloud::getEntries(3);
$entriesremain = count(OC_Log_Owncloud::getEntries(4)) > 3;
$tmpl->assign('loglevel', OC_Config::getValue( "loglevel", 2 ));
+$tmpl->assign('mail_domain', OC_Config::getValue( "mail_domain", '' ));
+$tmpl->assign('mail_from_address', OC_Config::getValue( "mail_from_address", '' ));
+$tmpl->assign('mail_smtpmode', OC_Config::getValue( "mail_smtpmode", '' ));
+$tmpl->assign('mail_smtpsecure', OC_Config::getValue( "mail_smtpsecure", '' ));
+$tmpl->assign('mail_smtphost', OC_Config::getValue( "mail_smtphost", '' ));
+$tmpl->assign('mail_smtpport', OC_Config::getValue( "mail_smtpport", '' ));
+$tmpl->assign('mail_smtpauthtype', OC_Config::getValue( "mail_smtpauthtype", '' ));
+$tmpl->assign('mail_smtpauth', OC_Config::getValue( "mail_smtpauth", false ));
+$tmpl->assign('mail_smtpname', OC_Config::getValue( "mail_smtpname", '' ));
+$tmpl->assign('mail_smtppassword', OC_Config::getValue( "mail_smtppassword", '' ));
$tmpl->assign('entries', $entries);
$tmpl->assign('entriesremain', $entriesremain);
$tmpl->assign('htaccessworking', $htaccessworking);
diff --git a/settings/admin/controller.php b/settings/admin/controller.php
new file mode 100644
index 00000000000..7019f9a4d2a
--- /dev/null
+++ b/settings/admin/controller.php
@@ -0,0 +1,123 @@
+<?php
+/**
+* @author Joas Schilling
+* @copyright 2014 Joas Schilling nickvergessen@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/>.
+*/
+
+namespace OC\Settings\Admin;
+
+class Controller {
+ /**
+ * Set mail settings
+ */
+ public static function setMailSettings() {
+ \OC_Util::checkAdminUser();
+ \OCP\JSON::callCheck();
+
+ $l = \OC_L10N::get('settings');
+
+ $smtp_settings = array(
+ 'mail_domain' => null,
+ 'mail_from_address' => null,
+ 'mail_smtpmode' => array('sendmail', 'smtp', 'qmail', 'php'),
+ 'mail_smtpsecure' => array('', 'ssl', 'tls'),
+ 'mail_smtphost' => null,
+ 'mail_smtpport' => null,
+ 'mail_smtpauthtype' => array('LOGIN', 'PLAIN', 'NTLM'),
+ 'mail_smtpauth' => true,
+ 'mail_smtpname' => null,
+ 'mail_smtppassword' => null,
+ );
+
+ foreach ($smtp_settings as $setting => $validate) {
+ if (!$validate) {
+ if (!isset($_POST[$setting]) || $_POST[$setting] === '') {
+ \OC_Config::deleteKey( $setting );
+ } else {
+ \OC_Config::setValue( $setting, $_POST[$setting] );
+ }
+ }
+ else if (is_bool($validate)) {
+ if (!empty($_POST[$setting])) {
+ \OC_Config::setValue( $setting, (bool) $_POST[$setting] );
+ } else {
+ \OC_Config::deleteKey( $setting );
+ }
+ }
+ else if (is_array($validate)) {
+ if (!isset($_POST[$setting]) || $_POST[$setting] === '') {
+ \OC_Config::deleteKey( $setting );
+ } else if (in_array($_POST[$setting], $validate)) {
+ \OC_Config::setValue( $setting, $_POST[$setting] );
+ } else {
+ $message = $l->t('Invalid value supplied for %s', array(self::getFieldname($setting, $l)));
+ \OC_JSON::error( array( "data" => array( "message" => $message)) );
+ exit;
+ }
+ }
+ }
+
+ \OC_JSON::success(array("data" => array( "message" => $l->t("Saved") )));
+ }
+
+ /**
+ * Send a mail to test the settings
+ */
+ public static function sendTestMail() {
+ \OC_Util::checkAdminUser();
+ \OCP\JSON::callCheck();
+
+ $l = \OC_L10N::get('settings');
+ $email = \OC_Preferences::getValue(\OC_User::getUser(), 'settings', 'email', '');
+ if (!empty($email)) {
+ $defaults = new \OC_Defaults();
+
+ try {
+ \OC_Mail::send($email, $_POST['user'],
+ $l->t('test email settings'),
+ $l->t('If you received this email, the settings seem to be correct.'),
+ \OCP\Util::getDefaultEmailAddress('no-reply'), $defaults->getName());
+ } catch (\Exception $e) {
+ $message = $l->t('A problem occurred while sending the e-mail. Please revisit your settings.');
+ \OC_JSON::error( array( "data" => array( "message" => $message)) );
+ exit;
+ }
+
+ \OC_JSON::success(array("data" => array( "message" => $l->t("Email sent") )));
+ } else {
+ $message = $l->t('You need to set your user email before being able to send test emails.');
+ \OC_JSON::error( array( "data" => array( "message" => $message)) );
+ }
+ }
+
+ /**
+ * Get the field name to use it in error messages
+ *
+ * @param $setting string
+ * @param $l \OC_L10N
+ * @return string
+ */
+ public static function getFieldname($setting, $l) {
+ switch ($setting) {
+ case 'mail_smtpmode':
+ return $l->t( 'Send mode' );
+ case 'mail_smtpsecure':
+ return $l->t( 'Encryption' );
+ case 'mail_smtpauthtype':
+ return $l->t( 'Authentification method' );
+ }
+ }
+}
diff --git a/settings/ajax/decryptall.php b/settings/ajax/decryptall.php
index d7c104ab151..4782a4cfc81 100644
--- a/settings/ajax/decryptall.php
+++ b/settings/ajax/decryptall.php
@@ -24,6 +24,8 @@ if ($result !== false) {
$successful = false;
}
+ $util->closeEncryptionSession();
+
if ($successful === true) {
\OCP\JSON::success(array('data' => array('message' => 'Files decrypted successfully')));
} else {
diff --git a/settings/css/settings.css b/settings/css/settings.css
index 8a96885b789..a47e7bf6563 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -61,7 +61,12 @@ td.remove { width:1em; padding-right:1em; }
tr:hover>td.password>span, tr:hover>td.displayName>span { margin:0; cursor:pointer; }
tr:hover>td.remove>a, tr:hover>td.password>img,tr:hover>td.displayName>img, tr:hover>td.quota>img { visibility:visible; cursor:pointer; }
tr:hover>td.remove>a { float:right; }
-li.selected { background-color:#ddd; }
+
+li.selected,
+#leftcontent li.selected {
+ background-color: #ddd;
+}
+
table.grid { width:100%; }
#rightcontent { padding-left: 10px; }
div.quota {
@@ -150,6 +155,18 @@ span.connectionwarning {color:#933; font-weight:bold; }
input[type=radio] { width:1em; }
table.shareAPI td { padding-bottom: 0.8em; }
+#mail_settings p label:first-child {
+ display: inline-block;
+ width: 300px;
+ text-align: right;
+}
+#mail_settings p select:nth-child(2) {
+ width: 143px;
+}
+#mail_smtpport {
+ width: 40px;
+}
+
/* HELP */
.pressed {background-color:#DDD;}
diff --git a/settings/js/admin.js b/settings/js/admin.js
index e957bd68f1f..c04c0505deb 100644
--- a/settings/js/admin.js
+++ b/settings/js/admin.js
@@ -34,4 +34,46 @@ $(document).ready(function(){
$('#security').change(function(){
$.post(OC.filePath('settings','ajax','setsecurity.php'), { enforceHTTPS: $('#forcessl').val() },function(){} );
});
+
+ $('#mail_smtpauth').change(function() {
+ if (!this.checked) {
+ $('#mail_credentials').addClass('hidden');
+ } else {
+ $('#mail_credentials').removeClass('hidden');
+ }
+ });
+
+ $('#mail_smtpmode').change(function() {
+ if ($(this).val() !== 'smtp') {
+ $('#setting_smtpauth').addClass('hidden');
+ $('#setting_smtphost').addClass('hidden');
+ $('#mail_smtpsecure_label').addClass('hidden');
+ $('#mail_smtpsecure').addClass('hidden');
+ $('#mail_credentials').addClass('hidden');
+ } else {
+ $('#setting_smtpauth').removeClass('hidden');
+ $('#setting_smtphost').removeClass('hidden');
+ $('#mail_smtpsecure_label').removeClass('hidden');
+ $('#mail_smtpsecure').removeClass('hidden');
+ if ($('#mail_smtpauth').attr('checked')) {
+ $('#mail_credentials').removeClass('hidden');
+ }
+ }
+ });
+
+ $('#mail_settings').change(function(){
+ OC.msg.startSaving('#mail_settings_msg');
+ var post = $( "#mail_settings" ).serialize();
+ $.post(OC.generateUrl('/settings/admin/mailsettings'), post, function(data){
+ OC.msg.finishedSaving('#mail_settings .msg', data);
+ });
+ });
+
+ $('#sendtestemail').click(function(){
+ OC.msg.startAction('#sendtestmail_msg', t('settings', 'Sending...'));
+ var post = $( "#sendtestemail" ).serialize();
+ $.post(OC.generateUrl('/settings/admin/mailtest'), post, function(data){
+ OC.msg.finishedAction('#sendtestmail_msg', data);
+ });
+ });
});
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 2c6f77d9314..3dbc8a2f7c2 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -207,12 +207,24 @@ OC.Settings.Apps = OC.Settings.Apps || {
a.prepend(filename);
a.prepend(img);
li.append(a);
- // append the new app as last item in the list (.push is from sticky footer)
+
+ // append the new app as last item in the list
+ // (.push is from sticky footer)
$('#apps .wrapper .push').before(li);
- // scroll the app navigation down so the newly added app is seen
- $('#navigation').animate({ scrollTop: $('#navigation').height() }, 'slow');
- // draw attention to the newly added app entry by flashing it twice
- container.children('li[data-id="'+entry.id+'"]').animate({opacity:.3}).animate({opacity:1}).animate({opacity:.3}).animate({opacity:1});
+
+ // scroll the app navigation down
+ // so the newly added app is seen
+ $('#navigation').animate({
+ scrollTop: $('#navigation').height()
+ }, 'slow');
+
+ // draw attention to the newly added app entry
+ // by flashing it twice
+ container.children('li[data-id="' + entry.id + '"]')
+ .animate({opacity: 0.3})
+ .animate({opacity: 1})
+ .animate({opacity: 0.3})
+ .animate({opacity: 1});
if (!SVGSupport() && entry.icon.match(/\.svg$/i)) {
$(img).addClass('svg');
@@ -248,6 +260,8 @@ $(document).ready(function(){
var item = tgt.is('li') ? $(tgt) : $(tgt).parent();
var app = item.data('app');
OC.Settings.Apps.loadApp(app);
+ $('#leftcontent .selected').removeClass('selected');
+ item.addClass('selected');
}
return false;
});
diff --git a/settings/js/personal.js b/settings/js/personal.js
index 5944272067b..7a4257f1c97 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -67,7 +67,7 @@ function showAvatarCropper() {
$cropper.prepend("<img>");
$cropperImage = $('#cropper img');
- $cropperImage.attr('src', OC.Router.generate('core_avatar_get_tmp')+'?requesttoken='+oc_requesttoken+'#'+Math.floor(Math.random()*1000));
+ $cropperImage.attr('src', OC.generateUrl('/avatar/tmp')+'?requesttoken='+oc_requesttoken+'#'+Math.floor(Math.random()*1000));
// Looks weird, but on('load', ...) doesn't work in IE8
$cropperImage.ready(function(){
@@ -95,7 +95,7 @@ function sendCropData() {
w: cropperdata.w,
h: cropperdata.h
};
- $.post(OC.Router.generate('core_avatar_post_cropped'), {crop: data}, avatarResponseHandler);
+ $.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler);
}
function saveCoords(c) {
@@ -132,7 +132,7 @@ $(document).ready(function(){
$('#passwordchanged').hide();
$('#passworderror').hide();
// Ajax foo
- $.post(OC.Router.generate('settings_personal_changepassword'), post, function(data){
+ $.post(OC.generateUrl('/settings/personal/changepassword'), post, function(data){
if( data.status === "success" ){
$('#pass1').val('');
$('#pass2').val('');
@@ -243,7 +243,7 @@ $(document).ready(function(){
OC.dialogs.filepicker(
t('settings', "Select a profile picture"),
function(path){
- $.post(OC.Router.generate('core_avatar_post'), {path: path}, avatarResponseHandler);
+ $.post(OC.generateUrl('/avatar/'), {path: path}, avatarResponseHandler);
},
false,
["image/png", "image/jpeg"]
@@ -253,7 +253,7 @@ $(document).ready(function(){
$('#removeavatar').click(function(){
$.ajax({
type: 'DELETE',
- url: OC.Router.generate('core_avatar_delete'),
+ url: OC.generateUrl('/avatar/'),
success: function(msg) {
updateAvatar(true);
}
@@ -315,25 +315,3 @@ OC.Encryption.msg={
}
}
};
-
-OC.msg={
- startSaving:function(selector){
- $(selector)
- .html( t('settings', 'Saving...') )
- .removeClass('success')
- .removeClass('error')
- .stop(true, true)
- .show();
- },
- finishedSaving:function(selector, data){
- if( data.status === "success" ){
- $(selector).html( data.data.message )
- .addClass('success')
- .stop(true, true)
- .delay(3000)
- .fadeOut(900);
- }else{
- $(selector).html( data.data.message ).addClass('error');
- }
- }
-};
diff --git a/settings/js/users.js b/settings/js/users.js
index 160d0a8d9d2..284976d3bad 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -225,7 +225,8 @@ var UserList = {
}
$('table+.loading').css('visibility', 'visible');
UserList.updating = true;
- $.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) {
+ var query = $.param({ offset: UserList.offset, limit: UserList.usersToLoad });
+ $.get(OC.generateUrl('/settings/ajax/userlist') + query, function (result) {
var loadedUsers = 0;
var trs = [];
if (result.status === 'success') {
@@ -371,9 +372,7 @@ $(document).ready(function () {
UserList.doSort();
UserList.availableGroups = $('#content table').data('groups');
- OC.Router.registerLoadedCallback(function() {
- $(window).scroll(function(e) {UserList._onScroll(e);});
- });
+ $(window).scroll(function(e) {UserList._onScroll(e);});
$('table').after($('<div class="loading" style="height: 200px; visibility: hidden;"></div>'));
$('select[multiple]').each(function (index, element) {
@@ -401,7 +400,7 @@ $(document).ready(function () {
if ($(this).val().length > 0) {
var recoveryPasswordVal = $('input:password[id="recoveryPassword"]').val();
$.post(
- OC.Router.generate('settings_users_changepassword'),
+ OC.generateUrl('/settings/users/changepassword'),
{username: uid, password: $(this).val(), recoveryPassword: recoveryPasswordVal},
function (result) {
if (result.status != 'success') {
diff --git a/settings/routes.php b/settings/routes.php
index 895a9f5ccea..6954bd3823d 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -6,6 +6,8 @@
* See the COPYING-README file.
*/
+/** @var $this OC_Router */
+
// Settings pages
$this->create('settings_help', '/settings/help')
->actionInclude('settings/help.php');
@@ -70,5 +72,11 @@ $this->create('settings_ajax_getlog', '/settings/ajax/getlog.php')
->actionInclude('settings/ajax/getlog.php');
$this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php')
->actionInclude('settings/ajax/setloglevel.php');
+$this->create('settings_mail_settings', '/settings/admin/mailsettings')
+ ->post()
+ ->action('OC\Settings\Admin\Controller', 'setMailSettings');
+$this->create('settings_admin_mail_test', '/settings/admin/mailtest')
+ ->post()
+ ->action('OC\Settings\Admin\Controller', 'sendTestMail');
$this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php')
->actionInclude('settings/ajax/setsecurity.php');
diff --git a/settings/templates/admin.php b/settings/templates/admin.php
index 0eabffb9316..487da036e74 100644
--- a/settings/templates/admin.php
+++ b/settings/templates/admin.php
@@ -11,6 +11,27 @@ $levelLabels = array(
$l->t( 'Errors and fatal issues' ),
$l->t( 'Fatal issues only' ),
);
+
+$mail_smtpauthtype = array(
+ '' => $l->t('None'),
+ 'LOGIN' => $l->t('Login'),
+ 'PLAIN' => $l->t('Plain'),
+ 'NTLM' => $l->t('NT LAN Manager'),
+);
+
+$mail_smtpsecure = array(
+ '' => $l->t('None'),
+ 'ssl' => $l->t('SSL'),
+ 'tls' => $l->t('TLS'),
+);
+
+$mail_smtpmode = array(
+ 'sendmail',
+ 'smtp',
+ 'qmail',
+ 'php',
+);
+
?>
<?php
@@ -250,6 +271,88 @@ if (!$_['internetconnectionworking']) {
</table>
</fieldset>
+<fieldset id="mail_settings" class="personalblock">
+ <h2><?php p($l->t('Email Server'));?> <span id="mail_settings_msg" class="msg"></span></h2>
+
+ <p><?php p($l->t('This is used for sending out notifications.')); ?></p>
+
+ <p>
+ <label for="mail_smtpmode"><?php p($l->t( 'Send mode' )); ?></label>
+ <select name='mail_smtpmode' id='mail_smtpmode'>
+ <?php foreach ($mail_smtpmode as $smtpmode):
+ $selected = '';
+ if ($smtpmode == $_['mail_smtpmode']):
+ $selected = 'selected="selected"';
+ endif; ?>
+ <option value='<?php p($smtpmode)?>' <?php p($selected) ?>><?php p($smtpmode) ?></option>
+ <?php endforeach;?>
+ </select>
+
+ <label id="mail_smtpsecure_label" for="mail_smtpsecure"
+ <?php if ($_['mail_smtpmode'] != 'smtp') print_unescaped(' class="hidden"'); ?>>
+ <?php p($l->t( 'Encryption' )); ?>
+ </label>
+ <select name="mail_smtpsecure" id="mail_smtpsecure"
+ <?php if ($_['mail_smtpmode'] != 'smtp') print_unescaped(' class="hidden"'); ?>>
+ <?php foreach ($mail_smtpsecure as $secure => $name):
+ $selected = '';
+ if ($secure == $_['mail_smtpsecure']):
+ $selected = 'selected="selected"';
+ endif; ?>
+ <option value='<?php p($secure)?>' <?php p($selected) ?>><?php p($name) ?></option>
+ <?php endforeach;?>
+ </select>
+ </p>
+
+ <p>
+ <label for="mail_from_address"><?php p($l->t( 'From address' )); ?></label>
+ <input type="text" name='mail_from_address' id="mail_from_address" placeholder="<?php p('mail')?>"
+ value='<?php p($_['mail_from_address']) ?>' />
+ @
+ <input type="text" name='mail_domain' id="mail_domain" placeholder="<?php p('example.com')?>"
+ value='<?php p($_['mail_domain']) ?>' />
+ </p>
+
+ <p id="setting_smtpauth" <?php if ($_['mail_smtpmode'] != 'smtp') print_unescaped(' class="hidden"'); ?>>
+ <label for="mail_smtpauthtype"><?php p($l->t( 'Authentification method' )); ?></label>
+ <select name='mail_smtpauthtype' id='mail_smtpauthtype'>
+ <?php foreach ($mail_smtpauthtype as $authtype => $name):
+ $selected = '';
+ if ($authtype == $_['mail_smtpauthtype']):
+ $selected = 'selected="selected"';
+ endif; ?>
+ <option value='<?php p($authtype)?>' <?php p($selected) ?>><?php p($name) ?></option>
+ <?php endforeach;?>
+ </select>
+
+ <input type="checkbox" name="mail_smtpauth" id="mail_smtpauth" value="1"
+ <?php if ($_['mail_smtpauth']) print_unescaped('checked="checked"'); ?> />
+ <label for="mail_smtpauth"><?php p($l->t( 'Authentication required' )); ?></label>
+ </p>
+
+ <p id="setting_smtphost" <?php if ($_['mail_smtpmode'] != 'smtp') print_unescaped(' class="hidden"'); ?>>
+ <label for="mail_smtphost"><?php p($l->t( 'Server address' )); ?></label>
+ <input type="text" name='mail_smtphost' id="mail_smtphost" placeholder="<?php p('smtp.example.com')?>"
+ value='<?php p($_['mail_smtphost']) ?>' />
+ :
+ <input type="text" name='mail_smtpport' id="mail_smtpport" placeholder="<?php p($l->t('Port'))?>"
+ value='<?php p($_['mail_smtpport']) ?>' />
+ </p>
+
+ <p id="mail_credentials" <?php if (!$_['mail_smtpauth'] || $_['mail_smtpmode'] != 'smtp') print_unescaped(' class="hidden"'); ?>>
+ <label for="mail_smtpname"><?php p($l->t( 'Credentials' )); ?></label>
+ <input type="text" name='mail_smtpname' id="mail_smtpname" placeholder="<?php p($l->t('SMTP Username'))?>"
+ value='<?php p($_['mail_smtpname']) ?>' />
+ <input type="password" name='mail_smtppassword' id="mail_smtppassword"
+ placeholder="<?php p($l->t('SMTP Password'))?>" value='<?php p($_['mail_smtppassword']) ?>' />
+ </p>
+
+ <br />
+ <em><?php p($l->t( 'Test email settings' )); ?></em>
+ <input type="submit" name="sendtestemail" id="sendtestemail" value="<?php p($l->t( 'Send email' )); ?>"/>
+ <span id="sendtestmail_msg" class="msg"></span>
+</fieldset>
+
<fieldset class="personalblock">
<h2><?php p($l->t('Log'));?></h2>
<?php p($l->t('Log level'));?> <select name='loglevel' id='loglevel'>
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index 188ff75f96b..9024f435657 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -83,7 +83,7 @@ if($_['passwordChangeSupported']) {
placeholder="<?php p($l->t('Your email address'));?>"
autocomplete="on" autocapitalize="off" autocorrect="off" />
<span class="msg"></span><br />
- <em><?php p($l->t('Fill in an email address to enable password recovery'));?></em>
+ <em><?php p($l->t('Fill in an email address to enable password recovery and receive notifications'));?></em>
</fieldset>
</form>
<?php
@@ -108,7 +108,7 @@ if($_['passwordChangeSupported']) {
<?php endif; ?>
</div>
<div id="cropper" class="hidden">
- <div class="inlineblock button" id="abortcropperbutton"><?php p($l->t('Abort')); ?></div>
+ <div class="inlineblock button" id="abortcropperbutton"><?php p($l->t('Cancel')); ?></div>
<div class="inlineblock button primary" id="sendcropperbutton"><?php p($l->t('Choose as profile image')); ?></div>
</div>
</fieldset>
diff --git a/tests/data/db_structure.xml b/tests/data/db_structure.xml
index d98066c4b7e..858c9ab1002 100644
--- a/tests/data/db_structure.xml
+++ b/tests/data/db_structure.xml
@@ -223,4 +223,19 @@
</declaration>
</table>
+<table>
+ <name>*dbprefix*migratekeyword</name>
+
+ <declaration>
+
+ <field>
+ <name>select</name>
+ <type>text</type>
+ <default></default>
+ <notnull>true</notnull>
+ <length>255</length>
+ </field>
+ </declaration>
+</table>
+
</database>
diff --git a/tests/data/db_structure2.xml b/tests/data/db_structure2.xml
index ae5f22e9573..568d90ab0a9 100644
--- a/tests/data/db_structure2.xml
+++ b/tests/data/db_structure2.xml
@@ -119,4 +119,19 @@
</declaration>
</table>
+ <table>
+ <name>*dbprefix*migratekeyword</name>
+
+ <declaration>
+
+ <field>
+ <name>select</name>
+ <type>text</type>
+ <default></default>
+ <notnull>false</notnull>
+ <length>255</length>
+ </field>
+ </declaration>
+ </table>
+
</database>
diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php
index 4f21d77a170..063ab8b5d33 100644
--- a/tests/lib/appframework/http/ResponseTest.php
+++ b/tests/lib/appframework/http/ResponseTest.php
@@ -78,7 +78,7 @@ class ResponseTest extends \PHPUnit_Framework_TestCase {
public function testGetEtag() {
$this->childResponse->setEtag('hi');
- $this->assertEquals('hi', $this->childResponse->getEtag());
+ $this->assertSame('hi', $this->childResponse->getEtag());
}
diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php
index 3f5604b4d45..5182fac8b10 100644
--- a/tests/lib/files/cache/scanner.php
+++ b/tests/lib/files/cache/scanner.php
@@ -150,13 +150,15 @@ class Scanner extends \PHPUnit_Framework_TestCase {
$this->cache->put('folder', array('mtime' => $this->storage->filemtime('folder'), 'storage_mtime' => $this->storage->filemtime('folder')));
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_SIZE);
$newData = $this->cache->get('');
- $this->assertNotEquals($oldData['etag'], $newData['etag']);
+ $this->assertInternalType('string', $oldData['etag']);
+ $this->assertInternalType('string', $newData['etag']);
+ $this->assertNotSame($oldData['etag'], $newData['etag']);
$this->assertEquals($oldData['size'], $newData['size']);
$oldData = $newData;
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
$newData = $this->cache->get('');
- $this->assertEquals($oldData['etag'], $newData['etag']);
+ $this->assertSame($oldData['etag'], $newData['etag']);
$this->assertEquals(-1, $newData['size']);
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);
@@ -164,17 +166,17 @@ class Scanner extends \PHPUnit_Framework_TestCase {
$this->assertNotEquals(-1, $oldData['size']);
$this->scanner->scanFile('', \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE);
$newData = $this->cache->get('');
- $this->assertEquals($oldData['etag'], $newData['etag']);
+ $this->assertSame($oldData['etag'], $newData['etag']);
$this->assertEquals($oldData['size'], $newData['size']);
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE);
$newData = $this->cache->get('');
- $this->assertEquals($oldData['etag'], $newData['etag']);
+ $this->assertSame($oldData['etag'], $newData['etag']);
$this->assertEquals($oldData['size'], $newData['size']);
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE);
$newData = $this->cache->get('');
- $this->assertEquals($oldData['etag'], $newData['etag']);
+ $this->assertSame($oldData['etag'], $newData['etag']);
$this->assertEquals($oldData['size'], $newData['size']);
}
@@ -217,8 +219,11 @@ class Scanner extends \PHPUnit_Framework_TestCase {
// manipulate etag to simulate an empty etag
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
$data0 = $this->cache->get('folder/bar.txt');
+ $this->assertInternalType('string', $data0['etag']);
$data1 = $this->cache->get('folder');
+ $this->assertInternalType('string', $data1['etag']);
$data2 = $this->cache->get('');
+ $this->assertInternalType('string', $data2['etag']);
$data0['etag'] = '';
$this->cache->put('folder/bar.txt', $data0);
@@ -227,10 +232,15 @@ class Scanner extends \PHPUnit_Framework_TestCase {
// verify cache content
$newData0 = $this->cache->get('folder/bar.txt');
+ $this->assertInternalType('string', $newData0['etag']);
+ $this->assertNotEmpty($newData0['etag']);
+
$newData1 = $this->cache->get('folder');
+ $this->assertInternalType('string', $newData1['etag']);
+ $this->assertNotSame($data1['etag'], $newData1['etag']);
+
$newData2 = $this->cache->get('');
- $this->assertNotEmpty($newData0['etag']);
- $this->assertNotEquals($data1['etag'], $newData1['etag']);
- $this->assertNotEquals($data2['etag'], $newData2['etag']);
+ $this->assertInternalType('string', $newData2['etag']);
+ $this->assertNotSame($data2['etag'], $newData2['etag']);
}
}
diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php
index 48986149a73..a6ee8c46661 100644
--- a/tests/lib/files/cache/updater.php
+++ b/tests/lib/files/cache/updater.php
@@ -96,10 +96,14 @@ class Updater extends \PHPUnit_Framework_TestCase {
Filesystem::file_put_contents('foo.txt', 'asd');
$cachedData = $this->cache->get('foo.txt');
$this->assertEquals(3, $cachedData['size']);
- $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $fooCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']);
$cachedData = $this->cache->get('');
$this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']);
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$rootCachedData = $cachedData;
$this->assertFalse($this->cache->inCache('bar.txt'));
@@ -110,12 +114,15 @@ class Updater extends \PHPUnit_Framework_TestCase {
$mtime = $cachedData['mtime'];
$cachedData = $this->cache->get('');
$this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']);
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime);
}
public function testWriteWithMountPoints() {
$storage2 = new \OC\Files\Storage\Temporary(array());
+ $storage2->getScanner()->scan(''); //initialize etags
$cache2 = $storage2->getCache();
Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage');
$folderCachedData = $this->cache->get('folder');
@@ -127,11 +134,15 @@ class Updater extends \PHPUnit_Framework_TestCase {
$mtime = $cachedData['mtime'];
$cachedData = $cache2->get('');
- $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $substorageCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']);
$this->assertEquals($mtime, $cachedData['mtime']);
$cachedData = $this->cache->get('folder');
- $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $folderCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']);
$this->assertEquals($mtime, $cachedData['mtime']);
}
@@ -146,19 +157,25 @@ class Updater extends \PHPUnit_Framework_TestCase {
$this->assertFalse($this->cache->inCache('foo.txt'));
$cachedData = $this->cache->get('');
$this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']);
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']);
$rootCachedData = $cachedData;
Filesystem::mkdir('bar_folder');
$this->assertTrue($this->cache->inCache('bar_folder'));
$cachedData = $this->cache->get('');
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$rootCachedData = $cachedData;
Filesystem::rmdir('bar_folder');
$this->assertFalse($this->cache->inCache('bar_folder'));
$cachedData = $this->cache->get('');
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']);
}
@@ -174,11 +191,15 @@ class Updater extends \PHPUnit_Framework_TestCase {
$this->assertFalse($cache2->inCache('foo.txt'));
$cachedData = $cache2->get('');
- $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $substorageCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($substorageCachedData['mtime'], $cachedData['mtime']);
$cachedData = $this->cache->get('folder');
- $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $folderCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($folderCachedData['mtime'], $cachedData['mtime']);
}
@@ -199,7 +220,9 @@ class Updater extends \PHPUnit_Framework_TestCase {
$mtime = $cachedData['mtime'];
$cachedData = $this->cache->get('');
$this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']);
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
}
public function testRenameExtension() {
@@ -227,12 +250,16 @@ class Updater extends \PHPUnit_Framework_TestCase {
$mtime = $cachedData['mtime'];
$cachedData = $cache2->get('');
- $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $substorageCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']);
// rename can cause mtime change - invalid assert
// $this->assertEquals($mtime, $cachedData['mtime']);
$cachedData = $this->cache->get('folder');
- $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $folderCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']);
// rename can cause mtime change - invalid assert
// $this->assertEquals($mtime, $cachedData['mtime']);
}
@@ -242,11 +269,15 @@ class Updater extends \PHPUnit_Framework_TestCase {
$fooCachedData = $this->cache->get('foo.txt');
Filesystem::touch('foo.txt');
$cachedData = $this->cache->get('foo.txt');
- $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $fooCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']);
$cachedData = $this->cache->get('');
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']);
$rootCachedData = $cachedData;
@@ -255,14 +286,20 @@ class Updater extends \PHPUnit_Framework_TestCase {
$folderCachedData = $this->cache->get('folder');
Filesystem::touch('folder/bar.txt', $time);
$cachedData = $this->cache->get('folder/bar.txt');
- $this->assertNotEquals($barCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $barCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($barCachedData['etag'], $cachedData['etag']);
$this->assertEquals($time, $cachedData['mtime']);
$cachedData = $this->cache->get('folder');
- $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $folderCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']);
$cachedData = $this->cache->get('');
- $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $rootCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']);
$this->assertEquals($time, $cachedData['mtime']);
}
@@ -279,14 +316,20 @@ class Updater extends \PHPUnit_Framework_TestCase {
$time = 1371006070;
Filesystem::touch('folder/substorage/foo.txt', $time);
$cachedData = $cache2->get('foo.txt');
- $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $fooCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']);
$this->assertEquals($time, $cachedData['mtime']);
$cachedData = $cache2->get('');
- $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $substorageCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']);
$cachedData = $this->cache->get('folder');
- $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']);
+ $this->assertInternalType('string', $folderCachedData['etag']);
+ $this->assertInternalType('string', $cachedData['etag']);
+ $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']);
$this->assertEquals($time, $cachedData['mtime']);
}
diff --git a/tests/lib/files/etagtest.php b/tests/lib/files/etagtest.php
index ce05adb188a..af9f66835f0 100644
--- a/tests/lib/files/etagtest.php
+++ b/tests/lib/files/etagtest.php
@@ -65,7 +65,11 @@ class EtagTest extends \PHPUnit_Framework_TestCase {
$scanner = new \OC\Files\Utils\Scanner($user1);
$scanner->backgroundScan('/');
- $this->assertEquals($originalEtags, $this->getEtags($files));
+ $newEtags = $this->getEtags($files);
+ // loop over array and use assertSame over assertEquals to prevent false positives
+ foreach ($originalEtags as $file => $originalEtag) {
+ $this->assertSame($originalEtag, $newEtags[$file]);
+ }
}
/**
diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php
index 43eae78415d..bd2c69a7396 100644
--- a/tests/lib/files/storage/wrapper/quota.php
+++ b/tests/lib/files/storage/wrapper/quota.php
@@ -53,6 +53,22 @@ class Quota extends \Test\Files\Storage\Storage {
$this->assertEquals(9, $instance->free_space(''));
}
+ public function testFreeSpaceWithUsedSpace() {
+ $instance = $this->getLimitedStorage(9);
+ $instance->getCache()->put(
+ '', array('size' => 3, 'unencrypted_size' => 0)
+ );
+ $this->assertEquals(6, $instance->free_space(''));
+ }
+
+ public function testFreeSpaceWithUsedSpaceAndEncryption() {
+ $instance = $this->getLimitedStorage(9);
+ $instance->getCache()->put(
+ '', array('size' => 7, 'unencrypted_size' => 3)
+ );
+ $this->assertEquals(6, $instance->free_space(''));
+ }
+
public function testFWriteNotEnoughSpace() {
$instance = $this->getLimitedStorage(9);
$stream = $instance->fopen('foo', 'w+');
diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php
index 371d1ed1798..c85f1128dbe 100644
--- a/tests/lib/files/view.php
+++ b/tests/lib/files/view.php
@@ -563,6 +563,6 @@ class View extends \PHPUnit_Framework_TestCase {
$scanner->scanFile('test', \OC\Files\Cache\Scanner::REUSE_ETAG);
$info2 = $view->getFileInfo('/test/test');
- $this->assertEquals($info['etag'], $info2['etag']);
+ $this->assertSame($info['etag'], $info2['etag']);
}
}
diff --git a/tests/lib/request.php b/tests/lib/request.php
index 1d77acc70ae..bff84e1b03f 100644
--- a/tests/lib/request.php
+++ b/tests/lib/request.php
@@ -135,4 +135,141 @@ class Test_Request extends PHPUnit_Framework_TestCase {
),
);
}
+
+ public function testInsecureServerHost() {
+ unset($_SERVER['HTTP_X_FORWARDED_HOST']);
+ unset($_SERVER['HTTP_HOST']);
+ unset($_SERVER['SERVER_NAME']);
+ $_SERVER['SERVER_NAME'] = 'from.server.name:8080';
+ $host = OC_Request::insecureServerHost();
+ $this->assertEquals('from.server.name:8080', $host);
+
+ $_SERVER['HTTP_HOST'] = 'from.host.header:8080';
+ $host = OC_Request::insecureServerHost();
+ $this->assertEquals('from.host.header:8080', $host);
+
+ $_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host:8080';
+ $host = OC_Request::insecureServerHost();
+ $this->assertEquals('from.forwarded.host:8080', $host);
+
+ $_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host2:8080,another.one:9000';
+ $host = OC_Request::insecureServerHost();
+ $this->assertEquals('from.forwarded.host2:8080', $host);
+
+ // clean up
+ unset($_SERVER['HTTP_X_FORWARDED_HOST']);
+ unset($_SERVER['HTTP_HOST']);
+ unset($_SERVER['SERVER_NAME']);
+ }
+
+ public function testGetOverwriteHost() {
+ unset($_SERVER['REMOTE_ADDR']);
+ OC_Config::deleteKey('overwritecondaddr');
+ OC_Config::deleteKey('overwritehost');
+ $host = OC_Request::getOverwriteHost();
+ $this->assertNull($host);
+
+ OC_Config::setValue('overwritehost', '');
+ $host = OC_Request::getOverwriteHost();
+ $this->assertNull($host);
+
+ OC_Config::setValue('overwritehost', 'host.one.test:8080');
+ $host = OC_Request::getOverwriteHost();
+ $this->assertEquals('host.one.test:8080', $host);
+
+ $_SERVER['REMOTE_ADDR'] = 'somehost.test:8080';
+ OC_Config::setValue('overwritecondaddr', '^somehost\..*$');
+ $host = OC_Request::getOverwriteHost();
+ $this->assertEquals('host.one.test:8080', $host);
+
+ OC_Config::setValue('overwritecondaddr', '^somethingelse.*$');
+ $host = OC_Request::getOverwriteHost();
+ $this->assertNull($host);
+
+ // clean up
+ unset($_SERVER['REMOTE_ADDR']);
+ OC_Config::deleteKey('overwritecondaddr');
+ OC_Config::deleteKey('overwritehost');
+ }
+
+ /**
+ * @dataProvider trustedDomainDataProvider
+ */
+ public function testIsTrustedDomain($trustedDomains, $testDomain, $result) {
+ OC_Config::deleteKey('trusted_domains');
+ if ($trustedDomains !== null) {
+ OC_Config::setValue('trusted_domains', $trustedDomains);
+ }
+
+ $this->assertEquals($result, OC_Request::isTrustedDomain($testDomain));
+
+ // clean up
+ OC_Config::deleteKey('trusted_domains');
+ }
+
+ public function trustedDomainDataProvider() {
+ $trustedHostTestList = array('host.one.test:8080', 'host.two.test:8080');
+ return array(
+ // empty defaults to true
+ array(null, 'host.one.test:8080', true),
+ array('', 'host.one.test:8080', true),
+ array(array(), 'host.one.test:8080', true),
+
+ // trust list when defined
+ array($trustedHostTestList, 'host.two.test:8080', true),
+ array($trustedHostTestList, 'host.two.test:9999', false),
+ array($trustedHostTestList, 'host.three.test:8080', false),
+
+ // trust localhost regardless of trust list
+ array($trustedHostTestList, 'localhost', true),
+ array($trustedHostTestList, 'localhost:8080', true),
+ array($trustedHostTestList, '127.0.0.1', true),
+ array($trustedHostTestList, '127.0.0.1:8080', true),
+
+ // do not trust invalid localhosts
+ array($trustedHostTestList, 'localhost:1:2', false),
+ array($trustedHostTestList, 'localhost: evil.host', false),
+ );
+ }
+
+ public function testServerHost() {
+ OC_Config::deleteKey('overwritecondaddr');
+ OC_Config::setValue('overwritehost', 'overwritten.host:8080');
+ OC_Config::setValue(
+ 'trusted_domains',
+ array(
+ 'trusted.host:8080',
+ 'second.trusted.host:8080'
+ )
+ );
+ $_SERVER['HTTP_HOST'] = 'trusted.host:8080';
+
+ // CLI always gives localhost
+ $oldCLI = OC::$CLI;
+ OC::$CLI = true;
+ $host = OC_Request::serverHost();
+ $this->assertEquals('localhost', $host);
+ OC::$CLI = false;
+
+ // overwritehost overrides trusted domain
+ $host = OC_Request::serverHost();
+ $this->assertEquals('overwritten.host:8080', $host);
+
+ // trusted domain returned when used
+ OC_Config::deleteKey('overwritehost');
+ $host = OC_Request::serverHost();
+ $this->assertEquals('trusted.host:8080', $host);
+
+ // trusted domain returned when untrusted one in header
+ $_SERVER['HTTP_HOST'] = 'untrusted.host:8080';
+ OC_Config::deleteKey('overwritehost');
+ $host = OC_Request::serverHost();
+ $this->assertEquals('trusted.host:8080', $host);
+
+ // clean up
+ OC_Config::deleteKey('overwritecondaddr');
+ OC_Config::deleteKey('overwritehost');
+ unset($_SERVER['HTTP_HOST']);
+ OC::$CLI = $oldCLI;
+ }
}