summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkondou <kondou@ts.unde.re>2014-02-28 19:28:29 +0100
committerkondou <kondou@ts.unde.re>2014-02-28 19:28:29 +0100
commit3c11dc0006d5a3722b37bed274d8d19be219b6b2 (patch)
tree15d163dbd8ce5c1b3ad0a554906d07481f259fbf
parent88882e3fa73cc21b96c2877a3d527bea56b6be11 (diff)
parent88c9ae129e7dcc0e10aee682c8d4fa31b93b614c (diff)
downloadnextcloud-server-3c11dc0006d5a3722b37bed274d8d19be219b6b2.tar.gz
nextcloud-server-3c11dc0006d5a3722b37bed274d8d19be219b6b2.zip
Merge branch 'master' into hide_remove_image_avatar
-rw-r--r--.gitignore1
-rw-r--r--.jshintrc2
m---------3rdparty0
-rw-r--r--apps/files/ajax/rawlist.php59
-rw-r--r--apps/files/css/files.css24
-rw-r--r--apps/files/js/admin.js19
-rw-r--r--apps/files/js/filelist.js42
-rw-r--r--apps/files/js/files.js10
-rw-r--r--apps/files/lib/helper.php18
-rw-r--r--apps/files/templates/index.php17
-rw-r--r--apps/files/tests/ajax_rename.php8
-rw-r--r--apps/files_encryption/hooks/hooks.php17
-rw-r--r--apps/files_encryption/js/settings-admin.js22
-rw-r--r--apps/files_encryption/lib/proxy.php34
-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.php8
-rw-r--r--apps/files_encryption/tests/hooks.php55
-rwxr-xr-xapps/files_encryption/tests/share.php70
-rwxr-xr-xapps/files_encryption/tests/util.php4
-rwxr-xr-xapps/files_external/lib/config.php14
-rw-r--r--apps/files_external/tests/mountconfig.php25
-rw-r--r--apps/files_sharing/lib/api.php12
-rw-r--r--apps/files_sharing/lib/cache.php12
-rw-r--r--apps/files_sharing/public.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/files_sharing/tests/cache.php137
-rw-r--r--apps/files_trashbin/js/filelist.js32
-rw-r--r--apps/user_ldap/group_ldap.php78
-rw-r--r--apps/user_ldap/lib/configuration.php3
-rw-r--r--apps/user_ldap/templates/settings.php1
-rw-r--r--apps/user_ldap/tests/access.php71
-rw-r--r--apps/user_ldap/tests/user_ldap.php101
-rwxr-xr-xconfig/config.sample.php6
-rw-r--r--core/ajax/preview.php31
-rw-r--r--core/css/icons.css11
-rw-r--r--core/css/mobile.css22
-rw-r--r--core/css/styles.css26
-rw-r--r--core/js/avatar.js9
-rw-r--r--core/js/config.php32
-rw-r--r--core/js/jquery.avatar.js10
-rw-r--r--core/js/js.js43
-rw-r--r--core/js/oc-dialogs.js2
-rw-r--r--core/js/tags.js6
-rw-r--r--core/js/tests/specHelper.js1
-rw-r--r--core/lostpassword/controller.php2
-rw-r--r--core/minimizer.php15
-rw-r--r--core/routes.php3
-rw-r--r--core/templates/installation.php2
-rw-r--r--core/templates/layout.user.php8
-rw-r--r--lib/base.php26
-rw-r--r--lib/private/app.php11
-rw-r--r--lib/private/db/mdb2schemamanager.php3
-rw-r--r--lib/private/defaults.php7
-rw-r--r--lib/private/files.php213
-rw-r--r--lib/private/files/cache/cache.php10
-rw-r--r--lib/private/files/filesystem.php5
-rw-r--r--lib/private/files/storage/common.php37
-rw-r--r--lib/private/files/view.php9
-rw-r--r--lib/private/helper.php2
-rw-r--r--lib/private/image.php31
-rw-r--r--lib/private/mimetypes.list.php1
-rw-r--r--lib/private/minimizer.php64
-rw-r--r--lib/private/minimizer/css.php38
-rw-r--r--lib/private/minimizer/js.php21
-rwxr-xr-xlib/private/request.php75
-rw-r--r--lib/private/setup.php5
-rw-r--r--lib/private/template/cssresourcelocator.php2
-rw-r--r--lib/private/templatelayout.php113
-rw-r--r--lib/private/updater.php15
-rw-r--r--lib/private/user.php1
-rw-r--r--lib/private/user/session.php1
-rwxr-xr-xlib/private/util.php2
-rw-r--r--lib/public/share.php16
-rwxr-xr-xsettings/admin.php10
-rw-r--r--settings/admin/controller.php93
-rw-r--r--settings/ajax/decryptall.php2
-rw-r--r--settings/css/settings.css19
-rw-r--r--settings/js/admin.js34
-rw-r--r--settings/js/apps.js24
-rw-r--r--settings/js/personal.js24
-rw-r--r--settings/routes.php3
-rw-r--r--settings/templates/admin.php99
-rw-r--r--settings/templates/personal.php2
-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/connector/sabre/file.php15
-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/view.php2
-rw-r--r--tests/lib/share/backend.php8
-rw-r--r--tests/lib/share/share.php6
-rw-r--r--tests/lib/urlgenerator.php34
97 files changed, 1736 insertions, 709 deletions
diff --git a/.gitignore b/.gitignore
index 25cb1b227f9..e61ec6f0359 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
/data
/owncloud
/config/config.php
+/config/*.config.php
/config/mount.php
/apps/inc.php
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/3rdparty b/3rdparty
-Subproject c7b4cdbcc1faa56df2489a5753b457627f460c0
+Subproject c77c4ddbd4ae86a307d073647e76d602eafd0c6
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/css/files.css b/apps/files/css/files.css
index 3ad167054c2..af863aca33e 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -20,7 +20,7 @@
padding: 10px;
font-weight: normal;
}
-#new>a {
+#new > a {
padding: 14px 10px;
position: relative;
top: 7px;
@@ -30,7 +30,7 @@
border-bottom-right-radius: 0;
border-bottom: none;
}
-#new>ul {
+#new > ul {
display: none;
position: fixed;
min-width: 112px;
@@ -39,16 +39,26 @@
padding-bottom: 0;
margin-top: 14px;
margin-left: -1px;
- text-align:left;
+ text-align: left;
background: #f8f8f8;
border: 1px solid #ddd;
border-radius: 5px;
border-top-left-radius: 0;
- box-shadow:0 2px 7px rgba(170,170,170,.4);
+ box-shadow: 0 2px 7px rgba(170,170,170,.4);
+}
+#new > ul > li {
+ height: 36px;
+ margin: 5px;
+ padding-left: 42px;
+ padding-bottom: 2px;
+ background-position: initial;
+ cursor: pointer;
+}
+#new > ul > li > p {
+ cursor: pointer;
+ padding-top: 7px;
+ padding-bottom: 7px;
}
-#new>ul>li { height:36px; margin:5px; padding-left:48px; padding-bottom:2px;
- background-repeat:no-repeat; cursor:pointer; }
-#new>ul>li>p { cursor:pointer; padding-top: 7px; padding-bottom: 7px;}
#new .error, #fileList .error {
color: #e9322d;
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/filelist.js b/apps/files/js/filelist.js
index d6cffde05de..550c10dba3e 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -11,6 +11,7 @@
/* global OC, t, n, FileList, FileActions, Files */
/* global procesSelection, dragOptions, SVGSupport, replaceSVG */
window.FileList={
+ appName: t('files', 'Files'),
useUndo:true,
postProcessList: function() {
$('#fileList tr').each(function() {
@@ -19,6 +20,21 @@ window.FileList={
});
},
/**
+ * Sets a new page title
+ */
+ setPageTitle: function(title){
+ if (title) {
+ title += ' - ';
+ } else {
+ title = '';
+ }
+ title += FileList.appName;
+ // Sets the page title with the " - ownCloud" suffix as in templates
+ window.document.title = title + ' - ' + oc_defaults.title;
+
+ return true;
+ },
+ /**
* Returns the tr element for a given file name
*/
findFileEl: function(fileName){
@@ -129,7 +145,7 @@ window.FileList={
if (loading) {
imgurl = OC.imagePath('core', 'loading.gif');
} else {
- imgurl = OC.imagePath('core', 'filetypes/file.png');
+ imgurl = OC.imagePath('core', 'filetypes/file');
}
var tr = this.createRow(
'file',
@@ -157,7 +173,7 @@ window.FileList={
var tr = this.createRow(
'dir',
name,
- OC.imagePath('core', 'filetypes/folder.png'),
+ OC.imagePath('core', 'filetypes/folder'),
OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/'),
size,
lastModified,
@@ -204,7 +220,16 @@ window.FileList={
return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
},
setCurrentDir: function(targetDir, changeUrl) {
- var url;
+ var url,
+ baseDir = OC.basename(targetDir);
+
+ if (baseDir !== '') {
+ FileList.setPageTitle(baseDir);
+ }
+ else {
+ FileList.setPageTitle();
+ }
+
$('#dir').val(targetDir);
if (changeUrl !== false) {
if (window.history.pushState && changeUrl !== false) {
@@ -847,7 +872,8 @@ window.FileList={
};
$(document).ready(function() {
- var isPublic = !!$('#isPublic').val();
+ var baseDir,
+ isPublic = !!$('#isPublic').val();
// handle upload events
var file_upload_start = $('#file_upload_start');
@@ -943,7 +969,7 @@ $(document).ready(function() {
uploadtext.attr('currentUploads', currentUploads);
var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads);
if (currentUploads === 0) {
- var img = OC.imagePath('core', 'filetypes/folder.png');
+ var img = OC.imagePath('core', 'filetypes/folder');
data.context.find('td.filename').attr('style','background-image:url('+img+')');
uploadtext.text(translatedText);
uploadtext.hide();
@@ -1003,7 +1029,7 @@ $(document).ready(function() {
if (data.errorThrown === 'abort') {
//cleanup uploading to a dir
var uploadtext = $('tr .uploadtext');
- var img = OC.imagePath('core', 'filetypes/folder.png');
+ var img = OC.imagePath('core', 'filetypes/folder');
uploadtext.parents('td.filename').attr('style','background-image:url('+img+')');
uploadtext.fadeOut();
uploadtext.attr('currentUploads', 0);
@@ -1016,7 +1042,7 @@ $(document).ready(function() {
if (data.errorThrown === 'abort') {
//cleanup uploading to a dir
var uploadtext = $('tr .uploadtext');
- var img = OC.imagePath('core', 'filetypes/folder.png');
+ var img = OC.imagePath('core', 'filetypes/folder');
uploadtext.parents('td.filename').attr('style','background-image:url('+img+')');
uploadtext.fadeOut();
uploadtext.attr('currentUploads', 0);
@@ -1132,5 +1158,7 @@ $(document).ready(function() {
}
}
+ FileList.setCurrentDir(parseCurrentDirFromUrl(), false);
+
FileList.createFileSummary();
});
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index fbac601f67a..f4546120702 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -734,6 +734,9 @@ Files.getMimeIcon = function(mime, ready) {
ready(Files.getMimeIcon.cache[mime]);
} else {
$.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path) {
+ if(SVGSupport()){
+ path = path.substr(0, path.length-4) + '.svg';
+ }
Files.getMimeIcon.cache[mime]=path;
ready(Files.getMimeIcon.cache[mime]);
});
@@ -783,13 +786,16 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
}
previewURL = previewURL.replace('(', '%28');
previewURL = previewURL.replace(')', '%29');
+ previewURL += '&forceIcon=0';
// preload image to prevent delay
// this will make the browser cache the image
var img = new Image();
img.onload = function(){
- //set preview thumbnail URL
- ready(previewURL);
+ // if loading the preview image failed (no preview for the mimetype) then img.width will < 5
+ if (img.width > 5) {
+ ready(previewURL);
+ }
}
img.src = previewURL;
});
diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php
index ac8a2ad3200..b9e41a352bc 100644
--- a/apps/files/lib/helper.php
+++ b/apps/files/lib/helper.php
@@ -22,6 +22,7 @@ class Helper
public static function determineIcon($file) {
if($file['type'] === 'dir') {
$dir = $file['directory'];
+ $icon = \OC_Helper::mimetypeIcon('dir');
$absPath = \OC\Files\Filesystem::getView()->getAbsolutePath($dir.'/'.$file['name']);
$mount = \OC\Files\Filesystem::getMountManager()->find($absPath);
if (!is_null($mount)) {
@@ -29,21 +30,22 @@ class Helper
if (!is_null($sid)) {
$sid = explode(':', $sid);
if ($sid[0] === 'shared') {
- return \OC_Helper::mimetypeIcon('dir-shared');
+ $icon = \OC_Helper::mimetypeIcon('dir-shared');
}
if ($sid[0] !== 'local' and $sid[0] !== 'home') {
- return \OC_Helper::mimetypeIcon('dir-external');
+ $icon = \OC_Helper::mimetypeIcon('dir-external');
}
}
}
- return \OC_Helper::mimetypeIcon('dir');
+ }else{
+ if($file['isPreviewAvailable']) {
+ $pathForPreview = $file['directory'] . '/' . $file['name'];
+ return \OC_Helper::previewIcon($pathForPreview) . '&c=' . $file['etag'];
+ }
+ $icon = \OC_Helper::mimetypeIcon($file['mimetype']);
}
- if($file['isPreviewAvailable']) {
- $pathForPreview = $file['directory'] . '/' . $file['name'];
- return \OC_Helper::previewIcon($pathForPreview) . '&c=' . $file['etag'];
- }
- return \OC_Helper::mimetypeIcon($file['mimetype']);
+ return substr($icon, 0, -3) . 'svg';
}
/**
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index 939043b2c9f..ed15e46a5ac 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -5,12 +5,17 @@
<div id="new" class="button">
<a><?php p($l->t('New'));?></a>
<ul>
- <li style="background-image:url('<?php p(OCP\mimetype_icon('text/plain')) ?>')"
- data-type='file' data-newname='<?php p($l->t('New text file')) ?>.txt'><p><?php p($l->t('Text file'));?></p></li>
- <li style="background-image:url('<?php p(OCP\mimetype_icon('dir')) ?>')"
- data-type='folder' data-newname='<?php p($l->t('New folder')) ?>'><p><?php p($l->t('Folder'));?></p></li>
- <li style="background-image:url('<?php p(OCP\image_path('core', 'places/link.svg')) ?>')"
- data-type='web'><p><?php p($l->t('From link'));?></p></li>
+ <li class="icon icon-filetype-text"
+ data-type="file" data-newname="<?php p($l->t('New text file')) ?>.txt">
+ <p><?php p($l->t('Text file'));?></p>
+ </li>
+ <li class="icon icon-filetype-folder"
+ data-type="folder" data-newname="<?php p($l->t('New folder')) ?>">
+ <p><?php p($l->t('Folder'));?></p>
+ </li>
+ <li class="icon icon-link" data-type="web">
+ <p><?php p($l->t('From link'));?></p>
+ </li>
</ul>
</div>
<?php endif;?>
diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php
index a1a5c8983ba..e53c0fb3dd1 100644
--- a/apps/files/tests/ajax_rename.php
+++ b/apps/files/tests/ajax_rename.php
@@ -110,7 +110,9 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$this->assertEquals('/test', $result['data']['directory']);
$this->assertEquals(18, $result['data']['size']);
$this->assertEquals('httpd/unix-directory', $result['data']['mime']);
- $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']);
+ $icon = \OC_Helper::mimetypeIcon('dir');
+ $icon = substr($icon, 0, -3) . 'svg';
+ $this->assertEquals($icon, $result['data']['icon']);
$this->assertFalse($result['data']['isPreviewAvailable']);
}
@@ -165,7 +167,9 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$this->assertEquals(18, $result['data']['size']);
$this->assertEquals('httpd/unix-directory', $result['data']['mime']);
$this->assertEquals('abcdef', $result['data']['etag']);
- $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']);
+ $icon = \OC_Helper::mimetypeIcon('dir');
+ $icon = substr($icon, 0, -3) . 'svg';
+ $this->assertEquals($icon, $result['data']['icon']);
$this->assertFalse($result['data']['isPreviewAvailable']);
}
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index 3af43f10264..0b6c5adf3fb 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -501,11 +501,20 @@ class Hooks {
* @param array $params with the old path and the new path
*/
public static function preRename($params) {
- $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ $user = \OCP\User::getUser();
+ $view = new \OC_FilesystemView('/');
+ $util = new Util($view, $user);
list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']);
- self::$renamedFiles[$params['oldpath']] = array(
- 'uid' => $ownerOld,
- 'path' => $pathOld);
+
+ // we only need to rename the keys if the rename happens on the same mountpoint
+ // otherwise we perform a stream copy, so we get a new set of keys
+ $mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']);
+ $mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']);
+ if ($mp1 === $mp2) {
+ self::$renamedFiles[$params['oldpath']] = array(
+ 'uid' => $ownerOld,
+ 'path' => $pathOld);
+ }
}
/**
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..a2d42c22c13 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
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..6bf69cd8ee1 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -1772,4 +1772,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/hooks.php b/apps/files_encryption/tests/hooks.php
index 7d926caea1b..d0e4b5f732e 100644
--- a/apps/files_encryption/tests/hooks.php
+++ b/apps/files_encryption/tests/hooks.php
@@ -47,6 +47,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase {
public $rootView; // view on /data/user
public $data;
public $filename;
+ public $folder;
public static function setUpBeforeClass() {
// reset backend
@@ -89,6 +90,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase {
// init short data
$this->data = 'hats';
$this->filename = 'enc_hooks_tests-' . uniqid() . '.txt';
+ $this->folder = 'enc_hooks_tests_folder-' . uniqid();
}
@@ -268,4 +270,57 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase {
}
}
+ /**
+ * @brief test rename operation
+ */
+ function testRenameHook() {
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename, $this->data);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // check if keys exists
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/'
+ . $this->filename . '.key'));
+
+ // make subfolder
+ $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder);
+
+ $this->assertTrue($this->rootView->is_dir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder));
+
+ // move the file out of the shared folder
+ $root = $this->rootView->getRoot();
+ $this->rootView->chroot('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/');
+ $this->rootView->rename($this->filename, '/' . $this->folder . '/' . $this->filename);
+ $this->rootView->chroot($root);
+
+ $this->assertFalse($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename));
+ $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->filename));
+
+ // keys should be renamed too
+ $this->assertFalse($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+ $this->assertFalse($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/'
+ . $this->filename . '.key'));
+
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->folder . '/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->folder . '/'
+ . $this->filename . '.key'));
+
+ // cleanup
+ $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder);
+ }
+
}
diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php
index 46a21dd55cd..be56968ac09 100755
--- a/apps/files_encryption/tests/share.php
+++ b/apps/files_encryption/tests/share.php
@@ -127,6 +127,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
\OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4);
}
+
/**
* @medium
* @param bool $withTeardown
@@ -498,6 +499,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
}
}
+
function testPublicShareFile() {
// login as admin
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
@@ -864,6 +866,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
\OCA\Encryption\Helper::adminDisableRecovery('test123');
$this->assertEquals(0, \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled'));
+
+ //clean up, reset passwords
+ \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test123');
+ $params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2,
+ 'password' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2,
+ 'recoveryPassword' => 'test123');
+ \OCA\Encryption\Hooks::setPassphrase($params);
}
/**
@@ -947,4 +956,65 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
$this->view->chroot('/');
}
+
+ /**
+ * @brief test moving a shared file out of the Shared folder
+ */
+ function testRename() {
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // get the file info from previous created file
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if we have a valid file info
+ $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo);
+
+ // share the file
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL);
+
+ // check if share key for user2exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+
+ // login as user2
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename));
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // move the file out of the shared folder
+ $this->view->rename('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename,
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename);
+
+ // check if we can read the moved file
+ $retrievedRenamedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedRenamedFile);
+
+ // the owners file should be deleted
+ $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $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/lib/config.php b/apps/files_external/lib/config.php
index b2109e5eacd..43275d36c06 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -277,15 +277,21 @@ class OC_Mount_Config {
$mountType,
$applicable,
$isPersonal = false) {
+ $backends = self::getBackends();
$mountPoint = OC\Files\Filesystem::normalizePath($mountPoint);
if ($mountPoint === '' || $mountPoint === '/' || $mountPoint == '/Shared') {
// can't mount at root or "Shared" folder
return false;
}
+
+ 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() || $class == '\OC\Files\Storage\Local') {
+ if ($applicable !== OCP\User::getUser() || strtolower($class) === '\oc\files\storage\local') {
return false;
}
$mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
@@ -353,7 +359,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);
@@ -379,7 +386,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);
diff --git a/apps/files_external/tests/mountconfig.php b/apps/files_external/tests/mountconfig.php
index 941aec680bb..24ebcf51346 100644
--- a/apps/files_external/tests/mountconfig.php
+++ b/apps/files_external/tests/mountconfig.php
@@ -48,4 +48,29 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase {
$this->assertEquals(false, OC_Mount_Config::addMountPoint('/Shared', $storageClass, array(), $mountType, $applicable, $isPersonal));
}
+
+ public function testAddMountPointSingleUser() {
+ \OC_User::setUserId('test');
+ $mountType = 'user';
+ $applicable = 'test';
+ $isPersonal = true;
+ // local
+ $this->assertEquals(false, OC_Mount_Config::addMountPoint('/ext', '\OC\Files\storage\local', array(), $mountType, $applicable, $isPersonal));
+ // non-local
+ // FIXME: can't test this yet as the class (write operation) is not mockable
+ // $this->assertEquals(true, OC_Mount_Config::addMountPoint('/ext', '\OC\Files\Storage\SFTP', array(), $mountType, $applicable, $isPersonal));
+
+ }
+
+ public function testAddMountPointUnexistClass() {
+ \OC_User::setUserId('test');
+ $storageClass = 'Unexist_Storage';
+ $mountType = 'user';
+ $applicable = 'test';
+ $isPersonal = true;
+ // local
+ // non-local
+ $this->assertEquals(false, OC_Mount_Config::addMountPoint('/ext', $storageClass, array(), $mountType, $applicable, $isPersonal));
+
+ }
}
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 aadc54e4a7f..4b0da0b002d 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -131,19 +131,15 @@ class Shared_Cache extends Cache {
foreach ($files as &$file) {
$file['mimetype'] = $this->getMimetype($file['mimetype']);
$file['mimepart'] = $this->getMimetype($file['mimepart']);
+ $file['usersPath'] = 'files/Shared/' . ltrim($file['path'], '/');
}
return $files;
} else {
- if ($cache = $this->getSourceCache($folder)) {
+ $cache = $this->getSourceCache($folder);
+ if ($cache) {
$sourceFolderContent = $cache->getFolderContents($this->files[$folder]);
foreach ($sourceFolderContent as $key => $c) {
- $ownerPathParts = explode('/', \OC_Filesystem::normalizePath($c['path']));
- $userPathParts = explode('/', \OC_Filesystem::normalizePath($folder));
- $usersPath = 'files/Shared/'.$userPathParts[1];
- foreach (array_slice($ownerPathParts, 3) as $part) {
- $usersPath .= '/'.$part;
- }
- $sourceFolderContent[$key]['usersPath'] = $usersPath;
+ $sourceFolderContent[$key]['usersPath'] = 'files/Shared/' . $folder . '/' . $c['name'];
}
return $sourceFolderContent;
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index e7a5f5024b8..fe61dd4d5a0 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -32,7 +32,8 @@ function determineIcon($file, $sharingRoot, $sharingToken) {
if($file['isPreviewAvailable']) {
return OCP\publicPreview_icon($relativePath, $sharingToken) . '&c=' . $file['etag'];
}
- return OCP\mimetype_icon($file['mimetype']);
+ $icon = OCP\mimetype_icon($file['mimetype']);
+ return substr($icon, 0, -3) . 'svg';
}
if (isset($_GET['t'])) {
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/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php
index 56a51c83f6b..a75e1860527 100644
--- a/apps/files_sharing/tests/cache.php
+++ b/apps/files_sharing/tests/cache.php
@@ -2,8 +2,9 @@
/**
* ownCloud
*
- * @author Vincent Petry
+ * @author Vincent Petry, Bjoern Schiessle
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
+ * 2014 Bjoern Schiessle <schiessle@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
@@ -23,13 +24,19 @@ require_once __DIR__ . '/base.php';
class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base {
+ /**
+ * @var OC_FilesystemView
+ */
+ public $user2View;
+
function setUp() {
parent::setUp();
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->user2View = new \OC\Files\View('/'. self::TEST_FILES_SHARING_API_USER2 . '/files');
+
// prepare user1's dir structure
- $textData = "dummy file data\n";
$this->view->mkdir('container');
$this->view->mkdir('container/shareddir');
$this->view->mkdir('container/shareddir/subdir');
@@ -115,20 +122,128 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base {
$this->verifyFiles($check, $results);
}
+ function testGetFolderContentsInRoot() {
+ $results = $this->user2View->getDirectoryContent('/Shared/');
+
+ $this->verifyFiles(
+ array(
+ array(
+ 'name' => 'shareddir',
+ 'path' => '/shareddir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'usersPath' => 'files/Shared/shareddir'
+ ),
+ array(
+ 'name' => 'shared single file.txt',
+ 'path' => '/shared single file.txt',
+ 'mimetype' => 'text/plain',
+ 'usersPath' => 'files/Shared/shared single file.txt'
+ ),
+ ),
+ $results
+ );
+ }
+
+ function testGetFolderContentsInSubdir() {
+ $results = $this->user2View->getDirectoryContent('/Shared/shareddir');
+
+ $this->verifyFiles(
+ array(
+ array(
+ 'name' => 'bar.txt',
+ 'path' => 'files/container/shareddir/bar.txt',
+ 'mimetype' => 'text/plain',
+ 'usersPath' => 'files/Shared/shareddir/bar.txt'
+ ),
+ array(
+ 'name' => 'emptydir',
+ 'path' => 'files/container/shareddir/emptydir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'usersPath' => 'files/Shared/shareddir/emptydir'
+ ),
+ array(
+ 'name' => 'subdir',
+ 'path' => 'files/container/shareddir/subdir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'usersPath' => 'files/Shared/shareddir/subdir'
+ ),
+ ),
+ $results
+ );
+ }
+
+ function testGetFolderContentsWhenSubSubdirShared() {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $fileinfo = $this->view->getFileInfo('container/shareddir/subdir');
+ \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+ self::TEST_FILES_SHARING_API_USER3, 31);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+
+ $thirdView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
+ $results = $thirdView->getDirectoryContent('/Shared/subdir');
+
+ $this->verifyFiles(
+ array(
+ array(
+ 'name' => 'another too.txt',
+ 'path' => 'files/container/shareddir/subdir/another too.txt',
+ 'mimetype' => 'text/plain',
+ 'usersPath' => 'files/Shared/subdir/another too.txt'
+ ),
+ array(
+ 'name' => 'another.txt',
+ 'path' => 'files/container/shareddir/subdir/another.txt',
+ 'mimetype' => 'text/plain',
+ 'usersPath' => 'files/Shared/subdir/another.txt'
+ ),
+ array(
+ 'name' => 'not a text file.xml',
+ 'path' => 'files/container/shareddir/subdir/not a text file.xml',
+ 'mimetype' => 'application/xml',
+ 'usersPath' => 'files/Shared/subdir/not a text file.xml'
+ ),
+ ),
+ $results
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+ self::TEST_FILES_SHARING_API_USER3);
+ }
+
/**
- * Checks that all provided attributes exist in the files list,
- * only the values provided in $examples will be used to check against
- * the file list. The files order also needs to be the same.
+ * Check if 'results' contains the expected 'examples' only.
*
* @param array $examples array of example files
- * @param array $files array of files
+ * @param array $results array of files
*/
- private function verifyFiles($examples, $files) {
- $this->assertEquals(count($examples), count($files));
- foreach ($files as $i => $file) {
- foreach ($examples[$i] as $key => $value) {
- $this->assertEquals($value, $file[$key]);
+ private function verifyFiles($examples, $results) {
+ $this->assertEquals(count($examples), count($results));
+
+ foreach ($examples as $example) {
+ foreach ($results as $key => $result) {
+ if ($result['name'] === $example['name']) {
+ $this->verifyKeys($example, $result);
+ unset($results[$key]);
+ break;
+ }
}
}
+ $this->assertTrue(empty($results));
}
+
+ /**
+ * @brief verify if each value from the result matches the expected result
+ * @param array $example array with the expected results
+ * @param array $result array with the results
+ */
+ private function verifyKeys($example, $result) {
+ foreach ($example as $key => $value) {
+ $this->assertEquals($value, $result[$key]);
+ }
+ }
+
}
diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js
index f42abb6d029..a88459b0a9a 100644
--- a/apps/files_trashbin/js/filelist.js
+++ b/apps/files_trashbin/js/filelist.js
@@ -1,3 +1,4 @@
+/* globals OC, FileList, t */
// override reload with own ajax call
FileList.reload = function(){
FileList.showMask();
@@ -17,7 +18,36 @@ FileList.reload = function(){
FileList.reloadCallback(result);
}
});
-}
+};
+
+FileList.appName = t('files_trashbin', 'Deleted files');
+
+FileList._deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/);
+
+/**
+ * Convert a file name in the format filename.d12345 to the real file name.
+ * This will use basename.
+ * The name will not be changed if it has no ".d12345" suffix.
+ * @param name file name
+ * @return converted file name
+ */
+FileList.getDeletedFileName = function(name) {
+ name = OC.basename(name);
+ var match = FileList._deletedRegExp.exec(name);
+ if (match && match.length > 1) {
+ name = match[1];
+ }
+ return name;
+};
+var oldSetCurrentDir = FileList.setCurrentDir;
+FileList.setCurrentDir = function(targetDir) {
+ oldSetCurrentDir.apply(this, arguments);
+
+ var baseDir = OC.basename(targetDir);
+ if (baseDir !== '') {
+ FileList.setPageTitle(FileList.getDeletedFileName(baseDir));
+ }
+};
FileList.linkTo = function(dir){
return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index 32e2cec5960..cef9ca3c4cf 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -61,8 +61,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return false;
}
//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
- $members = $this->access->readAttribute($dn_group,
- $this->access->connection->ldapGroupMemberAssocAttr);
+ $members = array_keys($this->_groupMembers($dn_group));
if(!$members) {
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
return false;
@@ -89,6 +88,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return $isInGroup;
}
+ private function _groupMembers($dnGroup, &$seen = null) {
+ if ($seen === null) {
+ $seen = array();
+ }
+ $allMembers = array();
+ if (array_key_exists($dnGroup, $seen)) {
+ // avoid loops
+ return array();
+ }
+ // used extensively in cron job, caching makes sense for nested groups
+ $cacheKey = '_groupMembers'.$dnGroup;
+ if($this->access->connection->isCached($cacheKey)) {
+ return $this->access->connection->getFromCache($cacheKey);
+ }
+ $seen[$dnGroup] = 1;
+ $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr,
+ $this->access->connection->ldapGroupFilter);
+ if (is_array($members)) {
+ foreach ($members as $memberDN) {
+ $allMembers[$memberDN] = 1;
+ $nestedGroups = $this->access->connection->ldapNestedGroups;
+ if (!empty($nestedGroups)) {
+ $subMembers = $this->_groupMembers($memberDN, $seen);
+ if ($subMembers) {
+ $allMembers = array_merge($allMembers, $subMembers);
+ }
+ }
+ }
+ }
+ $this->access->connection->writeToCache($cacheKey, $allMembers);
+ return $allMembers;
+ }
+
/**
* @brief Get all groups a user belongs to
* @param $uid Name of the user
@@ -124,18 +156,45 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$uid = $userDN;
}
- $filter = $this->access->combineFilterWithAnd(array(
- $this->access->connection->ldapGroupFilter,
- $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid
- ));
- $groups = $this->access->fetchListOfGroups($filter,
- array($this->access->connection->ldapGroupDisplayName, 'dn'));
+ $groups = array_values($this->getGroupsByMember($uid));
$groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
$this->access->connection->writeToCache($cacheKey, $groups);
return $groups;
}
+ private function getGroupsByMember($dn, &$seen = null) {
+ if ($seen === null) {
+ $seen = array();
+ }
+ $allGroups = array();
+ if (array_key_exists($dn, $seen)) {
+ // avoid loops
+ return array();
+ }
+ $seen[$dn] = true;
+ $filter = $this->access->combineFilterWithAnd(array(
+ $this->access->connection->ldapGroupFilter,
+ $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn
+ ));
+ $groups = $this->access->fetchListOfGroups($filter,
+ array($this->access->connection->ldapGroupDisplayName, 'dn'));
+ if (is_array($groups)) {
+ foreach ($groups as $groupobj) {
+ $groupDN = $groupobj['dn'];
+ $allGroups[$groupDN] = $groupobj;
+ $nestedGroups = $this->access->connection->ldapNestedGroups;
+ if (!empty($nestedGroups)) {
+ $supergroups = $this->getGroupsByMember($groupDN, $seen);
+ if (is_array($supergroups) && (count($supergroups)>0)) {
+ $allGroups = array_merge($allGroups, $supergroups);
+ }
+ }
+ }
+ }
+ return $allGroups;
+ }
+
/**
* @brief get a list of all users in a group
* @returns array with user ids
@@ -172,8 +231,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return array();
}
- $members = $this->access->readAttribute($groupDN,
- $this->access->connection->ldapGroupMemberAssocAttr);
+ $members = array_keys($this->_groupMembers($groupDN));
if(!$members) {
//in case users could not be retrieved, return empty resultset
$this->access->connection->writeToCache($cachekey, array());
diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php
index 954d0501fad..612a623e910 100644
--- a/apps/user_ldap/lib/configuration.php
+++ b/apps/user_ldap/lib/configuration.php
@@ -76,6 +76,7 @@ class Configuration {
'ldapExpertUUIDUserAttr' => null,
'ldapExpertUUIDGroupAttr' => null,
'lastJpegPhotoLookup' => null,
+ 'ldapNestedGroups' => false,
);
/**
@@ -342,6 +343,7 @@ class Configuration {
'ldap_expert_uuid_group_attr' => '',
'has_memberof_filter_support' => 0,
'last_jpegPhoto_lookup' => 0,
+ 'ldap_nested_groups' => 0,
);
}
@@ -393,6 +395,7 @@ class Configuration {
'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
+ 'ldap_nested_groups' => 'ldapNestedGroups',
);
return $array;
}
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 3ccc7a860f5..79c4ae224c3 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -36,6 +36,7 @@
<p><label for="ldap_base_groups"><?php p($l->t('Base Group Tree'));?></label><textarea id="ldap_base_groups" name="ldap_base_groups" placeholder="<?php p($l->t('One Group Base DN per line'));?>" data-default="<?php p($_['ldap_base_groups_default']); ?>" title="<?php p($l->t('Base Group Tree'));?>"></textarea></p>
<p><label for="ldap_attributes_for_group_search"><?php p($l->t('Group Search Attributes'));?></label><textarea id="ldap_attributes_for_group_search" name="ldap_attributes_for_group_search" placeholder="<?php p($l->t('Optional; one attribute per line'));?>" data-default="<?php p($_['ldap_attributes_for_group_search_default']); ?>" title="<?php p($l->t('Group Search Attributes'));?>"></textarea></p>
<p><label for="ldap_group_member_assoc_attribute"><?php p($l->t('Group-Member association'));?></label><select id="ldap_group_member_assoc_attribute" name="ldap_group_member_assoc_attribute" data-default="<?php p($_['ldap_group_member_assoc_attribute_default']); ?>" ><option value="uniqueMember"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'uniqueMember')) p(' selected'); ?>>uniqueMember</option><option value="memberUid"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'memberUid')) p(' selected'); ?>>memberUid</option><option value="member"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'member')) p(' selected'); ?>>member (AD)</option></select></p>
+ <p><label for="ldap_nested_groups"><?php p($l->t('Nested Groups'));?></label><input type="checkbox" id="ldap_nested_groups" name="ldap_nested_groups" value="1" data-default="<?php p($_['ldap_nested_groups_default']); ?>" title="<?php p($l->t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)'));?>" /></p>
</div>
<h3><?php p($l->t('Special Attributes'));?></h3>
<div>
diff --git a/apps/user_ldap/tests/access.php b/apps/user_ldap/tests/access.php
new file mode 100644
index 00000000000..9beb2b97336
--- /dev/null
+++ b/apps/user_ldap/tests/access.php
@@ -0,0 +1,71 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2013 Arthur Schiwon blizzz@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 OCA\user_ldap\tests;
+
+use \OCA\user_ldap\lib\Access;
+use \OCA\user_ldap\lib\Connection;
+use \OCA\user_ldap\lib\ILDAPWrapper;
+
+class Test_Access extends \PHPUnit_Framework_TestCase {
+ private function getConnecterAndLdapMock() {
+ static $conMethods;
+ static $accMethods;
+
+ if(is_null($conMethods) || is_null($accMethods)) {
+ $conMethods = get_class_methods('\OCA\user_ldap\lib\Connection');
+ $accMethods = get_class_methods('\OCA\user_ldap\lib\Access');
+ }
+ $lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper');
+ $connector = $this->getMock('\OCA\user_ldap\lib\Connection',
+ $conMethods,
+ array($lw, null, null));
+
+ return array($lw, $connector);
+ }
+
+ public function testEscapeFilterPartValidChars() {
+ list($lw, $con) = $this->getConnecterAndLdapMock();
+ $access = new Access($con, $lw);
+
+ $input = 'okay';
+ $this->assertTrue($input === $access->escapeFilterPart($input));
+ }
+
+ public function testEscapeFilterPartEscapeWildcard() {
+ list($lw, $con) = $this->getConnecterAndLdapMock();
+ $access = new Access($con, $lw);
+
+ $input = '*';
+ $expected = '\\\\*';
+ $this->assertTrue($expected === $access->escapeFilterPart($input));
+ }
+
+ public function testEscapeFilterPartEscapeWildcard2() {
+ list($lw, $con) = $this->getConnecterAndLdapMock();
+ $access = new Access($con, $lw);
+
+ $input = 'foo*bar';
+ $expected = 'foo\\\\*bar';
+ $this->assertTrue($expected === $access->escapeFilterPart($input));
+ }
+} \ No newline at end of file
diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php
index 9193a005ae5..8c8d85b3c33 100644
--- a/apps/user_ldap/tests/user_ldap.php
+++ b/apps/user_ldap/tests/user_ldap.php
@@ -83,6 +83,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
* @return void
*/
private function prepareAccessForCheckPassword(&$access) {
+ $access->expects($this->once())
+ ->method('escapeFilterPart')
+ ->will($this->returnCallback(function($uid) {
+ return $uid;
+ }));
+
$access->connection->expects($this->any())
->method('__get')
->will($this->returnCallback(function($name) {
@@ -116,17 +122,34 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
}));
}
- public function testCheckPassword() {
+ public function testCheckPasswordUidReturn() {
$access = $this->getAccessMock();
+
$this->prepareAccessForCheckPassword($access);
$backend = new UserLDAP($access);
\OC_User::useBackend($backend);
$result = $backend->checkPassword('roland', 'dt19');
$this->assertEquals('gunslinger', $result);
+ }
+
+ public function testCheckPasswordWrongPassword() {
+ $access = $this->getAccessMock();
+
+ $this->prepareAccessForCheckPassword($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = $backend->checkPassword('roland', 'wrong');
$this->assertFalse($result);
+ }
+
+ public function testCheckPasswordWrongUser() {
+ $access = $this->getAccessMock();
+
+ $this->prepareAccessForCheckPassword($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = $backend->checkPassword('mallory', 'evil');
$this->assertFalse($result);
@@ -140,9 +163,23 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
$result = \OCP\User::checkPassword('roland', 'dt19');
$this->assertEquals('gunslinger', $result);
+ }
+
+ public function testCheckPasswordPublicAPIWrongPassword() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForCheckPassword($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::checkPassword('roland', 'wrong');
$this->assertFalse($result);
+ }
+
+ public function testCheckPasswordPublicAPIWrongUser() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForCheckPassword($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::checkPassword('mallory', 'evil');
$this->assertFalse($result);
@@ -154,6 +191,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
* @return void
*/
private function prepareAccessForGetUsers(&$access) {
+ $access->expects($this->once())
+ ->method('escapeFilterPart')
+ ->will($this->returnCallback(function($search) {
+ return $search;
+ }));
+
$access->expects($this->any())
->method('getFilterPartForUserSearch')
->will($this->returnCallback(function($search) {
@@ -191,28 +234,52 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
->will($this->returnArgument(0));
}
- public function testGetUsers() {
+ public function testGetUsersNoParam() {
$access = $this->getAccessMock();
$this->prepareAccessForGetUsers($access);
$backend = new UserLDAP($access);
$result = $backend->getUsers();
$this->assertEquals(3, count($result));
+ }
+
+ public function testGetUsersLimitOffset() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
$result = $backend->getUsers('', 1, 2);
$this->assertEquals(1, count($result));
+ }
+
+ public function testGetUsersLimitOffset2() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
$result = $backend->getUsers('', 2, 1);
$this->assertEquals(2, count($result));
+ }
+
+ public function testGetUsersSearchWithResult() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
$result = $backend->getUsers('yo');
$this->assertEquals(2, count($result));
+ }
+
+ public function testGetUsersSearchEmptyResult() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
$result = $backend->getUsers('nix');
$this->assertEquals(0, count($result));
}
- public function testGetUsersViaAPI() {
+ public function testGetUsersViaAPINoParam() {
$access = $this->getAccessMock();
$this->prepareAccessForGetUsers($access);
$backend = new UserLDAP($access);
@@ -220,15 +287,43 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
$result = \OCP\User::getUsers();
$this->assertEquals(3, count($result));
+ }
+
+ public function testGetUsersViaAPILimitOffset() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::getUsers('', 1, 2);
$this->assertEquals(1, count($result));
+ }
+
+ public function testGetUsersViaAPILimitOffset2() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::getUsers('', 2, 1);
$this->assertEquals(2, count($result));
+ }
+
+ public function testGetUsersViaAPISearchWithResult() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::getUsers('yo');
$this->assertEquals(2, count($result));
+ }
+
+ public function testGetUsersViaAPISearchEmptyResult() {
+ $access = $this->getAccessMock();
+ $this->prepareAccessForGetUsers($access);
+ $backend = new UserLDAP($access);
+ \OC_User::useBackend($backend);
$result = \OCP\User::getUsers('nix');
$this->assertEquals(0, count($result));
diff --git a/config/config.sample.php b/config/config.sample.php
index 9f47ee32940..9c5eca8a5ec 100755
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -53,6 +53,9 @@ $CONFIG = array(
/* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */
"proxyuserpwd" => "",
+/* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */
+'trusted_domains' => array('demo.owncloud.org'),
+
/* Theme to use for ownCloud */
"theme" => "",
@@ -264,6 +267,9 @@ $CONFIG = array(
/* whether usage of the instance should be restricted to admin users only */
'singleuser' => false,
+/* all css and js files will be served by the web server statically in one js file and ons css file*/
+'asset-pipeline.enabled' => false,
+
/* where mount.json file should be stored, defaults to data/mount.json */
'mount_file' => '',
);
diff --git a/core/ajax/preview.php b/core/ajax/preview.php
index a1267d6f5cf..526719e8a1b 100644
--- a/core/ajax/preview.php
+++ b/core/ajax/preview.php
@@ -7,34 +7,39 @@
*/
\OC_Util::checkLoggedIn();
-$file = array_key_exists('file', $_GET) ? (string) $_GET['file'] : '';
-$maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '36';
-$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '36';
-$scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
+$file = array_key_exists('file', $_GET) ? (string)$_GET['file'] : '';
+$maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36';
+$maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36';
+$scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true;
+$always = array_key_exists('forceIcon', $_GET) ? (bool)$_GET['forceIcon'] : true;
-if($file === '') {
+if ($file === '') {
//400 Bad Request
\OC_Response::setStatus(400);
\OC_Log::write('core-preview', 'No file parameter was passed', \OC_Log::DEBUG);
exit;
}
-if($maxX === 0 || $maxY === 0) {
+if ($maxX === 0 || $maxY === 0) {
//400 Bad Request
\OC_Response::setStatus(400);
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
exit;
}
-try{
+try {
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
- $preview->setFile($file);
- $preview->setMaxX($maxX);
- $preview->setMaxY($maxY);
- $preview->setScalingUp($scalingUp);
+ if (!$always and !$preview->isMimeSupported(\OC\Files\Filesystem::getMimeType($file))) {
+ \OC_Response::setStatus(404);
+ } else {
+ $preview->setFile($file);
+ $preview->setMaxX($maxX);
+ $preview->setMaxY($maxY);
+ $preview->setScalingUp($scalingUp);
+ }
$preview->show();
-}catch(\Exception $e) {
+} catch (\Exception $e) {
\OC_Response::setStatus(500);
\OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG);
-} \ No newline at end of file
+}
diff --git a/core/css/icons.css b/core/css/icons.css
index 2dc35084122..027a3f8557f 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;
}
@@ -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');
}
@@ -226,6 +227,12 @@
.icon-folder {
background-image: url('../img/places/folder.svg');
}
+.icon-filetype-text {
+ background-image: url('../img/filetypes/text.svg');
+}
+.icon-filetype-folder {
+ background-image: url('../img/filetypes/folder.svg');
+}
.icon-home {
background-image: url('../img/places/home.svg');
diff --git a/core/css/mobile.css b/core/css/mobile.css
new file mode 100644
index 00000000000..a63aa902d34
--- /dev/null
+++ b/core/css/mobile.css
@@ -0,0 +1,22 @@
+@media only screen and (max-width: 600px) {
+
+/* compress search box on mobile, expand when focused */
+.searchbox input[type="search"] {
+ width: 15%;
+ -webkit-transition: width 100ms;
+ -moz-transition: width 100ms;
+ -o-transition: width 100ms;
+ transition: width 100ms;
+}
+.searchbox input[type="search"]:focus,
+.searchbox input[type="search"]:active {
+ width: 155px;
+}
+
+/* do not show display name on mobile when profile picture is present */
+#header .avatardiv.avatardiv-shown + #expandDisplayName {
+ display: none;
+}
+
+
+}
diff --git a/core/css/styles.css b/core/css/styles.css
index 22ba60dd2b7..082d2c714cf 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -37,11 +37,12 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari
.header-right { float:right; vertical-align:middle; padding:0.5em; }
.header-right > * { vertical-align:middle; }
+/* Profile picture in header */
#header .avatardiv {
float: left;
display: inline-block;
+ margin-right: 5px;
}
-
#header .avatardiv img {
opacity: 1;
}
@@ -218,17 +219,19 @@ textarea:disabled {
color: #bbb;
}
-
+/* Searchbox */
.searchbox input[type="search"] {
+ position: relative;
font-size: 1.2em;
- padding: .2em .5em .2em 1.5em;
+ padding-left: 1.5em;
background: #fff url('../img/actions/search.svg') no-repeat .5em center;
border: 0;
- border-radius: 1em;
+ border-radius: 2em;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity: .7;
- margin-top: 10px;
+ margin-top: 6px;
float: right;
}
+
input[type="submit"].enabled {
background: #66f866;
border: 1px solid #5e5;
@@ -402,11 +405,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;
}
@@ -719,12 +720,11 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; }
/* USER MENU */
#settings {
float: right;
- margin-top: 7px;
- margin-left: 10px;
color: #bbb;
}
#expand {
- padding: 15px 15px 15px 5px;
+ display: block;
+ padding: 7px 12px 6px 7px;
cursor: pointer;
font-weight: bold;
}
diff --git a/core/js/avatar.js b/core/js/avatar.js
index c54c4068768..67d6b9b7b95 100644
--- a/core/js/avatar.js
+++ b/core/js/avatar.js
@@ -1,6 +1,13 @@
$(document).ready(function(){
if (OC.currentUser) {
- $('#header .avatardiv').avatar(OC.currentUser, 32, undefined, true);
+ var callback = function() {
+ // do not show display name on mobile when profile picture is present
+ if($('#header .avatardiv').children().length > 0) {
+ $('#header .avatardiv').addClass('avatardiv-shown');
+ }
+ };
+
+ $('#header .avatardiv').avatar(OC.currentUser, 32, undefined, true, callback);
// Personal settings
$('#avatar .avatardiv').avatar(OC.currentUser, 128);
}
diff --git a/core/js/config.php b/core/js/config.php
index 139c3b6d485..7e23f3e2e41 100644
--- a/core/js/config.php
+++ b/core/js/config.php
@@ -10,12 +10,15 @@
header("Content-type: text/javascript");
// Disallow caching
-header("Cache-Control: no-cache, must-revalidate");
-header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
// Enable l10n support
$l = OC_L10N::get('core');
+// Enable OC_Defaults support
+$defaults = new OC_Defaults();
+
// Get the config
$apps_paths = array();
foreach(OC_App::getEnabledApps() as $app) {
@@ -58,11 +61,30 @@ $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(
+ array(
+ 'entity' => $defaults->getEntity(),
+ 'name' => $defaults->getName(),
+ 'title' => $defaults->getTitle(),
+ 'baseUrl' => $defaults->getBaseUrl(),
+ 'syncClientUrl' => $defaults->getSyncClientUrl(),
+ 'docBaseUrl' => $defaults->getDocBaseUrl(),
+ 'slogan' => $defaults->getSlogan(),
+ 'logoClaim' => $defaults->getLogoClaim(),
+ 'shortFooter' => $defaults->getShortFooter(),
+ 'longFooter' => $defaults->getLongFooter()
)
)
- );
+);
+
+// Allow hooks to modify the output values
+OC_Hook::emit('\OCP\Config', 'js', array('array' => &$array));
// Echo it
foreach ($array as $setting => $value) {
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 6012eccfad6..02a40c088b4 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -39,10 +39,15 @@
* This will behave like the first example, but it will hide the avatardiv, if
* it will display the default placeholder. undefined is the ie8fix from
* example 4 and can be either true, or false/undefined, to be ignored.
+ *
+ * 6. $('.avatardiv').avatar('jdoe', 128, undefined, true, callback);
+ * This will behave like the above example, but it will call the function
+ * defined in callback after the avatar is placed into the DOM.
+ *
*/
(function ($) {
- $.fn.avatar = function(user, size, ie8fix, hidedefault) {
+ $.fn.avatar = function(user, size, ie8fix, hidedefault, callback) {
if (typeof(size) === 'undefined') {
if (this.height() > 0) {
size = this.height();
@@ -91,6 +96,9 @@
$div.html('<img src="'+url+'">');
}
}
+ if(typeof callback === 'function') {
+ callback();
+ }
});
});
};
diff --git a/core/js/js.js b/core/js/js.js
index d4d2583f1e5..21ccee0f1d5 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -467,6 +467,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,
@@ -860,6 +888,7 @@ function initCore() {
// checkShowCredentials();
// $('input#user, input#password').keyup(checkShowCredentials);
+ // user menu
$('#settings #expand').keydown(function(event) {
if (event.which === 13 || event.which === 32) {
$('#expand').click()
@@ -872,7 +901,8 @@ function initCore() {
$('#settings #expanddiv').click(function(event){
event.stopPropagation();
});
- $(document).click(function(){//hide the settings menu when clicking outside it
+ //hide the user menu when clicking outside it
+ $(document).click(function(){
$('#settings #expanddiv').slideUp(200);
});
@@ -987,6 +1017,17 @@ OC.set=function(name, value) {
context[tail]=value;
};
+// fix device width on windows phone
+(function() {
+ if ("-ms-user-select" in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/)) {
+ var msViewportStyle = document.createElement("style");
+ msViewportStyle.appendChild(
+ document.createTextNode("@-ms-viewport{width:auto!important}")
+ );
+ document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
+ }
+})();
+
/**
* select a range in an input field
* @link http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js
index f4e3ec01447..d1bcb4659b8 100644
--- a/core/js/oc-dialogs.js
+++ b/core/js/oc-dialogs.js
@@ -293,7 +293,7 @@ var OCdialogs = {
conflict.find('.replacement .size').text(humanFileSize(replacement.size));
conflict.find('.replacement .mtime').text(formatDate(replacement.lastModifiedDate));
}
- var path = getPathForPreview(original.name);
+ var path = original.directory + '/' +original.name;
Files.lazyLoadPreview(path, original.mime, function(previewpath){
conflict.find('.original .icon').css('background-image','url('+previewpath+')');
}, 96, 96, original.etag);
diff --git a/core/js/tags.js b/core/js/tags.js
index 16dd3d4bf97..bc6d7b4e071 100644
--- a/core/js/tags.js
+++ b/core/js/tags.js
@@ -25,11 +25,11 @@ OC.Tags= {
});
self.deleteButton = {
text: t('core', 'Delete'),
- click: function() {self._deleteTags(self, type, self._selectedIds())},
+ click: function() {self._deleteTags(self, type, self._selectedIds())}
};
self.addButton = {
text: t('core', 'Add'),
- click: function() {self._addTag(self, type, self.$taginput.val())},
+ click: function() {self._addTag(self, type, self.$taginput.val())}
};
self._fillTagList(type, self.$taglist);
@@ -349,5 +349,5 @@ OC.Tags= {
console.warn(response);
});
}
-}
+};
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index 1848d08354e..b1193240580 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -63,6 +63,7 @@ window.oc_config = {
session_lifetime: 600 * 1000,
session_keepalive: false
};
+window.oc_defaults = {};
// global setup for all tests
(function setupTests() {
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/minimizer.php b/core/minimizer.php
deleted file mode 100644
index eeeddf86a81..00000000000
--- a/core/minimizer.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-session_write_close();
-
-OC_App::loadApps();
-
-if ($service == 'core.css') {
- $minimizer = new OC_Minimizer_CSS();
- $files = OC_TemplateLayout::findStylesheetFiles(OC_Util::$coreStyles);
- $minimizer->output($files, $service);
-}
-else if ($service == 'core.js') {
- $minimizer = new OC_Minimizer_JS();
- $files = OC_TemplateLayout::findJavascriptFiles(OC_Util::$coreScripts);
- $minimizer->output($files, $service);
-}
diff --git a/core/routes.php b/core/routes.php
index f8454877e03..aea788bdc6b 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -100,9 +100,6 @@ $this->create('core_avatar_post_cropped', '/avatar/cropped')
->action('OC\Core\Avatar\Controller', 'postCroppedAvatar');
// Not specifically routed
-$this->create('app_css', '/apps/{app}/{file}')
- ->requirements(array('file' => '.*.css'))
- ->action('OC', 'loadCSSFile');
$this->create('app_index_script', '/apps/{app}/')
->defaults(array('file' => 'index.php'))
//->requirements(array('file' => '.*.php'))
diff --git a/core/templates/installation.php b/core/templates/installation.php
index d3adb34f412..d9f3c38ab11 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; ?>
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 44413f5a2a8..3d897503480 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -15,7 +15,7 @@
</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=1.0">
<meta name="apple-itunes-app" content="app-id=543672169">
<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
@@ -51,12 +51,12 @@
<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
<div id="settings" class="svg">
<span id="expand" tabindex="0" role="link">
+ <?php if ($_['enableAvatars']): ?>
+ <div class="avatardiv"></div>
+ <?php endif; ?>
<span id="expandDisplayName"><?php p(trim($_['user_displayname']) != '' ? $_['user_displayname'] : $_['user_uid']) ?></span>
<img class="svg" alt="" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" />
</span>
- <?php if ($_['enableAvatars']): ?>
- <div class="avatardiv"></div>
- <?php endif; ?>
<div id="expanddiv">
<ul>
<?php foreach($_['settingsnavigation'] as $entry):?>
diff --git a/lib/base.php b/lib/base.php
index a5f064bdb4b..49cbb1279d1 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -284,10 +284,6 @@ class OC {
if (self::needUpgrade()) {
if ($showTemplate && !OC_Config::getValue('maintenance', false)) {
OC_Config::setValue('theme', '');
- $minimizerCSS = new OC_Minimizer_CSS();
- $minimizerCSS->clearCache();
- $minimizerJS = new OC_Minimizer_JS();
- $minimizerJS->clearCache();
OC_Util::addScript('config'); // needed for web root
OC_Util::addScript('update');
$tmpl = new OC_Template('', 'update.admin', 'guest');
@@ -332,6 +328,7 @@ class OC {
}
OC_Util::addStyle("styles");
+ OC_Util::addStyle("mobile");
OC_Util::addStyle("icons");
OC_Util::addStyle("apps");
OC_Util::addStyle("fixes");
@@ -724,11 +721,6 @@ class OC {
$app = OC::$REQUESTEDAPP;
$file = OC::$REQUESTEDFILE;
$param = array('app' => $app, 'file' => $file);
- // Handle app css files
- if (substr($file, -3) == 'css') {
- self::loadCSSFile($param);
- return;
- }
// Handle redirect URL for logged in users
if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) {
@@ -760,7 +752,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';
@@ -795,19 +788,6 @@ class OC {
return false;
}
- public static function loadCSSFile($param) {
- $app = $param['app'];
- $file = $param['file'];
- $app_path = OC_App::getAppPath($app);
- if (file_exists($app_path . '/' . $file)) {
- $app_web_path = OC_App::getAppWebPath($app);
- $filepath = $app_web_path . '/' . $file;
- $minimizer = new OC_Minimizer_CSS();
- $info = array($app_path, $app_web_path, $file);
- $minimizer->output(array($info), $filepath);
- }
- }
-
protected static function handleLogin() {
OC_App::loadApps(array('prelogin'));
$error = array();
diff --git a/lib/private/app.php b/lib/private/app.php
index 47f983cce35..048d4d4aeb1 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -69,17 +69,6 @@ class OC_App{
}
ob_end_clean();
- if (!defined('DEBUG') || !DEBUG) {
- if (is_null($types)
- && empty(OC_Util::$coreScripts)
- && empty(OC_Util::$coreStyles)) {
- OC_Util::$coreScripts = OC_Util::$scripts;
- OC_Util::$scripts = array();
- OC_Util::$coreStyles = OC_Util::$styles;
- OC_Util::$styles = array();
- }
- }
- // return
return true;
}
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/defaults.php b/lib/private/defaults.php
index 0b97497baa1..59630cda5c0 100644
--- a/lib/private/defaults.php
+++ b/lib/private/defaults.php
@@ -174,4 +174,11 @@ 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;
+ }
+
}
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/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 d4dca780ff3..9e826dd6192 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -140,43 +140,6 @@ abstract class Common implements \OC\Files\Storage\Storage {
return $result;
}
- /**
- * @brief Deletes all files and folders recursively within a directory
- * @param string $directory The directory whose contents will be deleted
- * @param bool $empty Flag indicating whether directory will be emptied
- * @returns bool
- *
- * @note By default the directory specified by $directory will be
- * deleted together with its contents. To avoid this set $empty to true
- */
- public function deleteAll($directory, $empty = false) {
- $directory = trim($directory, '/');
- if (!$this->is_dir($directory) || !$this->isReadable($directory)) {
- return false;
- } else {
- $directoryHandle = $this->opendir($directory);
- if (is_resource($directoryHandle)) {
- while (($contents = readdir($directoryHandle)) !== false) {
- if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
- $path = $directory . '/' . $contents;
- if ($this->is_dir($path)) {
- $this->deleteAll($path);
- } else {
- $this->unlink($path);
- }
- }
- }
- }
- if ($empty === false) {
- if (!$this->rmdir($directory)) {
- return false;
- }
- }
- return true;
- }
-
- }
-
public function getMimeType($path) {
if ($this->is_dir($path)) {
return 'httpd/unix-directory';
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 530aa8f7514..2dbbf5b88c9 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -413,7 +413,7 @@ class View {
$result = $this->copy($path1, $path2);
if ($result === true) {
list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
- $result = $storage1->deleteAll($internalPath1);
+ $result = $storage1->unlink($internalPath1);
}
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
@@ -534,6 +534,8 @@ class View {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
+ fclose($source);
+ fclose($target);
}
}
if ($this->shouldEmitHooks() && $result !== false) {
@@ -880,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..d8c4650f666 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);
}
/**
diff --git a/lib/private/image.php b/lib/private/image.php
index 17caaa012f5..da32aa4760f 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,43 +301,33 @@ 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) {
@@ -367,6 +351,7 @@ class OC_Image {
return false;
}
}
+ return false;
}
/**
@@ -599,9 +584,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 +932,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/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/minimizer.php b/lib/private/minimizer.php
deleted file mode 100644
index db522de74dc..00000000000
--- a/lib/private/minimizer.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-
-abstract class OC_Minimizer {
- public function generateETag($files) {
- $fullpath_files = array();
- foreach($files as $file_info) {
- $fullpath_files[] = $file_info[0] . '/' . $file_info[2];
- }
- return OC_Cache::generateCacheKeyFromFiles($fullpath_files);
- }
-
- abstract public function minimizeFiles($files);
-
- public function output($files, $cache_key) {
- header('Content-Type: '.$this->contentType);
- OC_Response::enableCaching();
- $etag = $this->generateETag($files);
- $cache_key .= '-'.$etag;
-
- $gzout = false;
- $cache = OC_Cache::getGlobalCache();
- if (!OC_Request::isNoCache() && (!defined('DEBUG') || !DEBUG)) {
- OC_Response::setETagHeader($etag);
- $gzout = $cache->get($cache_key.'.gz');
- }
-
- if (!$gzout) {
- $out = $this->minimizeFiles($files);
- $gzout = gzencode($out);
- $cache->set($cache_key.'.gz', $gzout);
- OC_Response::setETagHeader($etag);
- }
- // on some systems (e.g. SLES 11, but not Ubuntu) mod_deflate and zlib compression will compress the output twice.
- // This results in broken core.css and core.js. To avoid it, we switch off zlib compression.
- // Since mod_deflate is still active, Apache will compress what needs to be compressed, i.e. no disadvantage.
- if(function_exists('apache_get_modules') && ini_get('zlib.output_compression') && in_array('mod_deflate', apache_get_modules())) {
- ini_set('zlib.output_compression', 'Off');
- }
- if ($encoding = OC_Request::acceptGZip()) {
- header('Content-Encoding: '.$encoding);
- $out = $gzout;
- } else {
- $out = gzdecode($gzout);
- }
- header('Content-Length: '.strlen($out));
- echo $out;
- }
-
- public function clearCache() {
- $cache = OC_Cache::getGlobalCache();
- $cache->clear('core.css');
- $cache->clear('core.js');
- }
-}
-
-if (!function_exists('gzdecode')) {
- function gzdecode($data, $maxlength=null, &$filename='', &$error='')
- {
- if (strcmp(substr($data, 0, 9),"\x1f\x8b\x8\0\0\0\0\0\0")) {
- return null; // Not the GZIP format we expect (See RFC 1952)
- }
- return gzinflate(substr($data, 10, -8));
- }
-}
diff --git a/lib/private/minimizer/css.php b/lib/private/minimizer/css.php
deleted file mode 100644
index 8d130572e2b..00000000000
--- a/lib/private/minimizer/css.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-require_once 'mediawiki/CSSMin.php';
-
-class OC_Minimizer_CSS extends OC_Minimizer
-{
- protected $contentType = 'text/css';
-
- public function minimizeFiles($files) {
- $css_out = '';
- $webroot = (string) OC::$WEBROOT;
- foreach($files as $file_info) {
- $file = $file_info[0] . '/' . $file_info[2];
- $css_out .= '/* ' . $file . ' */' . "\n";
- $css = file_get_contents($file);
-
- $in_root = false;
- foreach(OC::$APPSROOTS as $app_root) {
- if(strpos($file, $app_root['path'].'/') === 0) {
- $in_root = rtrim($webroot.$app_root['url'], '/');
- break;
- }
- }
- if ($in_root !== false) {
- $css = str_replace('%appswebroot%', $in_root, $css);
- $css = str_replace('%webroot%', $webroot, $css);
- }
- $remote = $file_info[1];
- $remote .= '/';
- $remote .= dirname($file_info[2]);
- $css_out .= CSSMin::remap($css, dirname($file), $remote, true);
- }
- if (!defined('DEBUG') || !DEBUG) {
- $css_out = CSSMin::minify($css_out);
- }
- return $css_out;
- }
-}
diff --git a/lib/private/minimizer/js.php b/lib/private/minimizer/js.php
deleted file mode 100644
index bd2d836deb0..00000000000
--- a/lib/private/minimizer/js.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-require_once 'mediawiki/JavaScriptMinifier.php';
-
-class OC_Minimizer_JS extends OC_Minimizer
-{
- protected $contentType = 'application/javascript';
-
- public function minimizeFiles($files) {
- $js_out = '';
- foreach($files as $file_info) {
- $file = $file_info[0] . '/' . $file_info[2];
- $js_out .= '/* ' . $file . ' */' . "\n";
- $js_out .= file_get_contents($file);
- }
- if (!defined('DEBUG') || !DEBUG) {
- $js_out = JavaScriptMinifier::minify($js_out);
- }
- return $js_out;
- }
-}
diff --git a/lib/private/request.php b/lib/private/request.php
index 0fd20b3cc1f..afd3fda4f2d 100755
--- a/lib/private/request.php
+++ b/lib/private/request.php
@@ -25,6 +25,16 @@ class OC_Request {
}
/**
+ * @brief Checks whether a domain is considered as trusted. This is used to prevent Host Header Poisoning.
+ * @param string $host
+ * @return bool
+ */
+ public static function isTrustedDomain($domain) {
+ $trustedList = \OC_Config::getValue('trusted_domains', array(''));
+ return in_array($domain, $trustedList);
+ }
+
+ /**
* @brief Returns the server host
* @returns string the server host
*
@@ -43,21 +53,27 @@ class OC_Request {
$host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST'])));
}
else{
- $host=$_SERVER['HTTP_X_FORWARDED_HOST'];
+ $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
- }
- else{
+ } else {
if (isset($_SERVER['HTTP_HOST'])) {
- return $_SERVER['HTTP_HOST'];
+ $host = $_SERVER['HTTP_HOST'];
}
- if (isset($_SERVER['SERVER_NAME'])) {
- return $_SERVER['SERVER_NAME'];
+ else if (isset($_SERVER['SERVER_NAME'])) {
+ $host = $_SERVER['SERVER_NAME'];
}
- return 'localhost';
}
- return $host;
- }
+ // 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', "") === "") {
+ return $host;
+ } else {
+ $trustedList = \OC_Config::getValue('trusted_domains', array(''));
+ return $trustedList[0];
+ }
+ }
/**
* @brief Returns the server protocol
@@ -71,14 +87,14 @@ class OC_Request {
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$proto = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']);
- }else{
- if(isset($_SERVER['HTTPS']) and !empty($_SERVER['HTTPS']) and ($_SERVER['HTTPS']!='off')) {
- $proto = 'https';
- }else{
- $proto = 'http';
- }
+ // Verify that the protocol is always HTTP or HTTPS
+ // default to http if an invalid value is provided
+ return $proto === 'https' ? 'https' : 'http';
+ }
+ if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
+ return 'https';
}
- return $proto;
+ return 'http';
}
/**
@@ -180,33 +196,6 @@ class OC_Request {
}
/**
- * @brief Check if this is a no-cache request
- * @return boolean true for no-cache
- */
- static public function isNoCache() {
- if (!isset($_SERVER['HTTP_CACHE_CONTROL'])) {
- return false;
- }
- return $_SERVER['HTTP_CACHE_CONTROL'] == 'no-cache';
- }
-
- /**
- * @brief Check if the requestor understands gzip
- * @return false|string true for gzip encoding supported
- */
- static public function acceptGZip() {
- if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
- return false;
- }
- $HTTP_ACCEPT_ENCODING = $_SERVER["HTTP_ACCEPT_ENCODING"];
- if( strpos($HTTP_ACCEPT_ENCODING, 'x-gzip') !== false )
- return 'x-gzip';
- else if( strpos($HTTP_ACCEPT_ENCODING, 'gzip') !== false )
- return 'gzip';
- return false;
- }
-
- /**
* @brief Check if the requester sent along an mtime
* @return false or an mtime
*/
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 17ef75bc7b5..0d5bf424b33 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -65,6 +65,7 @@ class OC_Setup {
OC_Config::setValue('passwordsalt', $salt);
//write the config file
+ OC_Config::setValue('trusted_domains', array(OC_Request::serverHost()));
OC_Config::setValue('datadirectory', $datadir);
OC_Config::setValue('dbtype', $dbtype);
OC_Config::setValue('version', implode('.', OC_Util::getVersion()));
@@ -97,8 +98,6 @@ class OC_Setup {
$appConfig = \OC::$server->getAppConfig();
$appConfig->setValue('core', 'installedat', microtime(true));
$appConfig->setValue('core', 'lastupdatedat', microtime(true));
- $appConfig->setValue('core', 'remote_core.css', '/core/minimizer.php');
- $appConfig->setValue('core', 'remote_core.js', '/core/minimizer.php');
OC_Group::createGroup('admin');
OC_Group::addToGroup($username, 'admin');
@@ -148,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/cssresourcelocator.php b/lib/private/template/cssresourcelocator.php
index 8e7831ca549..e26daa25827 100644
--- a/lib/private/template/cssresourcelocator.php
+++ b/lib/private/template/cssresourcelocator.php
@@ -22,7 +22,7 @@ class CSSResourceLocator extends ResourceLocator {
$app = substr($style, 0, strpos($style, '/'));
$style = substr($style, strpos($style, '/')+1);
$app_path = \OC_App::getAppPath($app);
- $app_url = $this->webroot . '/index.php/apps/' . $app;
+ $app_url = \OC_App::getAppWebPath($app);
if ($this->appendIfExist($app_path, $style.$this->form_factor.'.css', $app_url)
|| $this->appendIfExist($app_path, $style.'.css', $app_url)
) {
diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php
index 7bca5bc4836..af17adb11c6 100644
--- a/lib/private/templatelayout.php
+++ b/lib/private/templatelayout.php
@@ -1,4 +1,11 @@
<?php
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+use Assetic\AssetManager;
+use Assetic\AssetWriter;
+use Assetic\Filter\CssRewriteFilter;
+
/**
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
@@ -57,35 +64,38 @@ class OC_TemplateLayout extends OC_Template {
} else {
parent::__construct('core', 'layout.base');
}
+
$versionParameter = '?v=' . md5(implode(OC_Util::getVersion()));
- // Add the js files
- $jsfiles = self::findJavascriptFiles(OC_Util::$scripts);
- $this->assign('jsfiles', array(), false);
- if (OC_Config::getValue('installed', false) && $renderas!='error') {
+ $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false);
+ if ($useAssetPipeline) {
+
$this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter);
- }
- if (!empty(OC_Util::$coreScripts)) {
- $this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false) . $versionParameter);
- }
- foreach($jsfiles as $info) {
- $root = $info[0];
- $web = $info[1];
- $file = $info[2];
- $this->append( 'jsfiles', $web.'/'.$file . $versionParameter);
- }
- // Add the css files
- $cssfiles = self::findStylesheetFiles(OC_Util::$styles);
- $this->assign('cssfiles', array());
- if (!empty(OC_Util::$coreStyles)) {
- $this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false) . $versionParameter);
- }
- foreach($cssfiles as $info) {
- $root = $info[0];
- $web = $info[1];
- $file = $info[2];
+ $this->generateAssets();
- $this->append( 'cssfiles', $web.'/'.$file . $versionParameter);
+ } else {
+
+ // Add the js files
+ $jsfiles = self::findJavascriptFiles(OC_Util::$scripts);
+ $this->assign('jsfiles', array(), false);
+ if (OC_Config::getValue('installed', false) && $renderas!='error') {
+ $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter);
+ }
+ foreach($jsfiles as $info) {
+ $web = $info[1];
+ $file = $info[2];
+ $this->append( 'jsfiles', $web.'/'.$file . $versionParameter);
+ }
+
+ // Add the css files
+ $cssfiles = self::findStylesheetFiles(OC_Util::$styles);
+ $this->assign('cssfiles', array());
+ foreach($cssfiles as $info) {
+ $web = $info[1];
+ $file = $info[2];
+
+ $this->append( 'cssfiles', $web.'/'.$file . $versionParameter);
+ }
}
}
@@ -116,4 +126,57 @@ class OC_TemplateLayout extends OC_Template {
$locator->find($scripts);
return $locator->getResources();
}
+
+ public function generateAssets()
+ {
+ $jsFiles = self::findJavascriptFiles(OC_Util::$scripts);
+ $jsHash = self::hashScriptNames($jsFiles);
+
+ if (!file_exists("assets/$jsHash.js")) {
+ $jsFiles = array_map(function ($item) {
+ $root = $item[0];
+ $file = $item[2];
+ return new FileAsset($root . '/' . $file, array(), $root, $file);
+ }, $jsFiles);
+ $jsCollection = new AssetCollection($jsFiles);
+ $jsCollection->setTargetPath("assets/$jsHash.js");
+
+ $writer = new AssetWriter(\OC::$SERVERROOT);
+ $writer->writeAsset($jsCollection);
+ }
+
+ $cssFiles = self::findStylesheetFiles(OC_Util::$styles);
+ $cssHash = self::hashScriptNames($cssFiles);
+
+ if (!file_exists("assets/$cssHash.css")) {
+ $cssFiles = array_map(function ($item) {
+ $root = $item[0];
+ $file = $item[2];
+ $assetPath = $root . '/' . $file;
+ $sourceRoot = \OC::$SERVERROOT;
+ $sourcePath = substr($assetPath, strlen(\OC::$SERVERROOT));
+ return new FileAsset($assetPath, array(new CssRewriteFilter()), $sourceRoot, $sourcePath);
+ }, $cssFiles);
+ $cssCollection = new AssetCollection($cssFiles);
+ $cssCollection->setTargetPath("assets/$cssHash.css");
+
+ $writer = new AssetWriter(\OC::$SERVERROOT);
+ $writer->writeAsset($cssCollection);
+ }
+
+ $this->append('jsfiles', OC_Helper::linkTo('assets', "$jsHash.js"));
+ $this->append('cssfiles', OC_Helper::linkTo('assets', "$cssHash.css"));
+ }
+
+ private static function hashScriptNames($files)
+ {
+ $files = array_map(function ($item) {
+ $root = $item[0];
+ $file = $item[2];
+ return $root . '/' . $file;
+ }, $files);
+
+ sort($files);
+ return hash('md5', implode('', $files));
+ }
}
diff --git a/lib/private/updater.php b/lib/private/updater.php
index 764a0f14120..f05d5038b76 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -102,6 +102,20 @@ class Updater extends BasicEmitter {
$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core'));
}
$this->emit('\OC\Updater', 'maintenanceStart');
+
+ /*
+ * START CONFIG CHANGES FOR OLDER VERSIONS
+ */
+ if (version_compare($currentVersion, '6.90.1', '<')) {
+ // Add the overwriteHost config if it is not existant
+ // This is added to prevent host header poisoning
+ \OC_Config::setValue('trusted_domains', \OC_Config::getValue('trusted_domains', array(\OC_Request::serverHost())));
+ }
+ /*
+ * STOP CONFIG CHANGES FOR OLDER VERSIONS
+ */
+
+
try {
\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
$this->emit('\OC\Updater', 'dbUpgrade');
@@ -162,3 +176,4 @@ class Updater extends BasicEmitter {
$this->emit('\OC\Updater', 'filecacheDone');
}
}
+
diff --git a/lib/private/user.php b/lib/private/user.php
index 08ead712028..a89b7286c10 100644
--- a/lib/private/user.php
+++ b/lib/private/user.php
@@ -227,6 +227,7 @@ class OC_User {
* Log in a user and regenerate a new session - if the password is ok
*/
public static function login($uid, $password) {
+ session_regenerate_id(true);
return self::getUserSession()->login($uid, $password);
}
diff --git a/lib/private/user/session.php b/lib/private/user/session.php
index cd03b30205f..1740bad5abe 100644
--- a/lib/private/user/session.php
+++ b/lib/private/user/session.php
@@ -157,7 +157,6 @@ class Session implements Emitter, \OCP\IUserSession {
if($user !== false) {
if (!is_null($user)) {
if ($user->isEnabled()) {
- session_regenerate_id(true);
$this->setUser($user);
$this->setLoginName($uid);
$this->manager->emit('\OC\User', 'postLogin', array($user, $password));
diff --git a/lib/private/util.php b/lib/private/util.php
index d3b682daa5c..920161949ae 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -11,8 +11,6 @@ class OC_Util {
public static $headers=array();
private static $rootMounted=false;
private static $fsSetup=false;
- public static $coreStyles=array();
- public static $coreScripts=array();
/**
* @brief Can be set up
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..a075d774361
--- /dev/null
+++ b/settings/admin/controller.php
@@ -0,0 +1,93 @@
+<?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") )));
+ }
+
+ /**
+ * 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..5ea6a5af2df 100644
--- a/settings/js/admin.js
+++ b/settings/js/admin.js
@@ -34,4 +34,38 @@ $(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.Router.generate('settings_mail_settings'), post, function(data){
+ OC.msg.finishedSaving('#mail_settings .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 59f112c8032..f38ec4e9ab1 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -52,9 +52,11 @@ function updateAvatar (hidedefault) {
if(hidedefault) {
$headerdiv.hide();
+ $('#header .avatardiv').removeClass('avatardiv-shown');
} else {
$headerdiv.css({'background-color': ''});
$headerdiv.avatar(OC.currentUser, 32, true);
+ $('#header .avatardiv').addClass('avatardiv-shown');
}
$displaydiv.css({'background-color': ''});
$displaydiv.avatar(OC.currentUser, 128, true);
@@ -327,25 +329,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/routes.php b/settings/routes.php
index 895a9f5ccea..64f7122f0cf 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -70,5 +70,8 @@ $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_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..139a9dd076c 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,84 @@ if (!$_['internetconnectionworking']) {
</table>
</fieldset>
+<fieldset id="mail_settings" class="personalblock">
+ <h2><?php p($l->t('Email Server'));?> <span 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>
+
+</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..470b8180bcc 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.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/connector/sabre/file.php b/tests/lib/connector/sabre/file.php
index 50b8711a90d..c2f0ffa12d4 100644
--- a/tests/lib/connector/sabre/file.php
+++ b/tests/lib/connector/sabre/file.php
@@ -49,21 +49,6 @@ class Test_OC_Connector_Sabre_File extends PHPUnit_Framework_TestCase {
}
/**
- * Test setting name with setName()
- */
- public function testSetName() {
- // setup
- $file = new OC_Connector_Sabre_File('/test.txt');
- $file->fileView = $this->getMock('\OC\Files\View', array('isUpdatable'), array(), '', FALSE);
- $file->fileView->expects($this->any())->method('isUpdatable')->withAnyParameters()->will($this->returnValue(true));
- $etag = $file->put('test data');
- $file->setName('/renamed.txt');
- $this->assertTrue($file->fileView->file_exists('/renamed.txt'));
- // clean up
- $file->delete();
- }
-
- /**
* Test setting name with setName() with invalid chars
* @expectedException Sabre_DAV_Exception_BadRequest
*/
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/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/share/backend.php b/tests/lib/share/backend.php
index 2f6c84678ff..420bd9d88b3 100644
--- a/tests/lib/share/backend.php
+++ b/tests/lib/share/backend.php
@@ -26,7 +26,7 @@ class Test_Share_Backend implements OCP\Share_Backend {
const FORMAT_SOURCE = 0;
const FORMAT_TARGET = 1;
const FORMAT_PERMISSIONS = 2;
-
+
private $testItem1 = 'test.txt';
private $testItem2 = 'share.txt';
@@ -57,11 +57,11 @@ class Test_Share_Backend implements OCP\Share_Backend {
public function formatItems($items, $format, $parameters = null) {
$testItems = array();
foreach ($items as $item) {
- if ($format == self::FORMAT_SOURCE) {
+ if ($format === self::FORMAT_SOURCE) {
$testItems[] = $item['item_source'];
- } else if ($format == self::FORMAT_TARGET) {
+ } else if ($format === self::FORMAT_TARGET) {
$testItems[] = $item['item_target'];
- } else if ($format == self::FORMAT_PERMISSIONS) {
+ } else if ($format === self::FORMAT_PERMISSIONS) {
$testItems[] = $item['permissions'];
}
}
diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php
index a89f100d97a..b5cba9430aa 100644
--- a/tests/lib/share/share.php
+++ b/tests/lib/share/share.php
@@ -622,21 +622,21 @@ class Test_Share extends PHPUnit_Framework_TestCase {
OC_User::setUserId($this->user1);
$this->assertEquals(
array('test.txt', 'test.txt'),
- OCP\Share::getItemsShared('test', 'test.txt'),
+ OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE),
'Failed asserting that the test.txt file is shared exactly two times by user1.'
);
OC_User::setUserId($this->user2);
$this->assertEquals(
array('test.txt'),
- OCP\Share::getItemsShared('test', 'test.txt'),
+ OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE),
'Failed asserting that the test.txt file is shared exactly once by user2.'
);
OC_User::setUserId($this->user3);
$this->assertEquals(
array('test.txt'),
- OCP\Share::getItemsShared('test', 'test.txt'),
+ OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE),
'Failed asserting that the test.txt file is shared exactly once by user3.'
);
diff --git a/tests/lib/urlgenerator.php b/tests/lib/urlgenerator.php
new file mode 100644
index 00000000000..875a7f06580
--- /dev/null
+++ b/tests/lib/urlgenerator.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright (c) 2014 Bjoern Schiessle <schiessle@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_Urlgenerator extends PHPUnit_Framework_TestCase {
+
+
+ /**
+ * @small
+ * @brief test absolute URL construction
+ * @dataProvider provideURLs
+ */
+ function testGetAbsoluteURL($url, $expectedResult) {
+
+ $urlGenerator = new \OC\URLGenerator(null);
+ $result = $urlGenerator->getAbsoluteURL($url);
+
+ $this->assertEquals($expectedResult, $result);
+ }
+
+ public function provideURLs() {
+ return array(
+ array("index.php", "http://localhost/index.php"),
+ array("/index.php", "http://localhost/index.php"),
+ array("/apps/index.php", "http://localhost/apps/index.php"),
+ array("apps/index.php", "http://localhost/apps/index.php"),
+ );
+ }
+}
+