summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2014-02-24 12:53:55 +0100
committerThomas Müller <thomas.mueller@tmit.eu>2014-02-24 12:53:55 +0100
commit0d78d9c180fe4d08500d74c5c61e43c8b6862262 (patch)
tree0e1b863431640154e99d70ea876ed6cd9a0d7a9d
parenta40cedf507a432c0f2afc144fbc3c7dedb438852 (diff)
parent11ca01403408413cbbe48c8d78c41802998868b7 (diff)
downloadnextcloud-server-0d78d9c180fe4d08500d74c5c61e43c8b6862262.tar.gz
nextcloud-server-0d78d9c180fe4d08500d74c5c61e43c8b6862262.zip
Merge branch 'master' into McNetic-zipstreamer
Conflicts: 3rdparty
-rw-r--r--.gitignore1
m---------3rdparty0
-rw-r--r--apps/files/css/files.css24
-rw-r--r--apps/files/templates/index.php17
-rwxr-xr-xapps/files_external/lib/config.php8
-rw-r--r--apps/files_external/tests/mountconfig.php25
-rw-r--r--apps/files_sharing/lib/cache.php12
-rw-r--r--apps/files_sharing/tests/cache.php137
-rwxr-xr-xconfig/config.sample.php6
-rw-r--r--core/css/icons.css6
-rw-r--r--core/js/js.js11
-rw-r--r--core/js/oc-dialogs.js2
-rw-r--r--core/js/tags.js6
-rw-r--r--core/minimizer.php15
-rw-r--r--core/routes.php3
-rw-r--r--lib/base.php22
-rw-r--r--lib/private/app.php11
-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.php73
-rw-r--r--lib/private/setup.php3
-rw-r--r--lib/private/template/cssresourcelocator.php2
-rw-r--r--lib/private/templatelayout.php113
-rw-r--r--lib/private/updater.php15
-rwxr-xr-xlib/private/util.php2
-rw-r--r--tests/lib/share/backend.php8
-rw-r--r--tests/lib/share/share.php6
28 files changed, 361 insertions, 290 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/3rdparty b/3rdparty
-Subproject e13a1213ff1539ed93751ba5c5adf6327d3ad51
+Subproject bbc37618c74a5439f729cc3e8ed369f674cb541
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/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_external/lib/config.php b/apps/files_external/lib/config.php
index b2109e5eacd..9a8b95c14c9 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, '/');
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/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/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/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/css/icons.css b/core/css/icons.css
index 2dc35084122..814749c5af8 100644
--- a/core/css/icons.css
+++ b/core/css/icons.css
@@ -226,6 +226,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/js/js.js b/core/js/js.js
index 59d48806418..ec890be4541 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -989,6 +989,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/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/lib/base.php b/lib/base.php
index 84177c7ba6c..525d290931f 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');
@@ -725,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()) {
@@ -796,19 +787,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/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..14f3bf2cbb7 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'];
+ $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..3906204bda3 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');
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/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/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.'
);