Compare commits

...

105 Commits

Author SHA1 Message Date
Frank Karlitschek
8db687a1cd 8.0.2 2015-03-09 14:23:26 +01:00
Frank Karlitschek
5def2c0998 Merge pull request #14738 from owncloud/backport-14734-stable8
[Backport-14734-stable8]
2015-03-09 09:05:22 -04:00
Frank Karlitschek
10d0f0d9b3 8.0.2 2015-03-09 14:05:05 +01:00
Thomas Müller
f6ceb0b0d5 use insertIfNotExist() in cache put 2015-03-06 17:41:51 +01:00
Thomas Müller
e5aefc8bda Use an atomic implementation on sqlite for insertIfNotExist() 2015-03-06 17:41:33 +01:00
Lukas Reschke
ba1748bd80 Merge pull request #14721 from owncloud/14711/without-public-api
[stable8] 14719 without public API
2015-03-05 23:35:06 +01:00
Lukas Reschke
6d5e60bd9b 14719 without public API 2015-03-05 22:36:17 +01:00
Frank Karlitschek
a7fc0fc07b Merge pull request #14719 from owncloud/fix-totally-broken-appstore
[stable8] Fix totally broken AppStore code…
2015-03-05 16:06:50 -05:00
Lukas Reschke
c032b94b77 Sort results 2015-03-05 21:22:25 +01:00
Lukas Reschke
8961967fec Fix totally broken AppStore
As it turned out the AppStore code was completely broken when it came from apps delivered from the appstore, this meant:

1. You could not disable and then re-enable an application that was installed from the AppStore. It simply failed hard.
2. You could not disable apps from the categories but only from the "Activated" page
3. It did not show the activation state from any category page

This code is completely static and thus testing it is impossible. We really have to stop with "let's add yet another feature in already existing static code". Such stuff has to get refactored first.

That said, this code works from what I can say when clicking around in the AppStore page GUI. However, it may easily be that it does not work with updates or whatsever as I have no chance to test that since the AppStore code is not open-source and it is impossible to write unit-tests for that.

Fixes https://github.com/owncloud/core/issues/14711
2015-03-05 20:48:43 +01:00
Frank Karlitschek
eb2ac86c5d bump version 2015-03-02 23:28:25 +01:00
Lukas Reschke
598c4fdcae Merge pull request #14636 from owncloud/stable8-fix-link-config.sample.php
fix link for Preview documentation
2015-03-02 14:36:25 +01:00
Morris Jobke
716e0e6645 fix link for Preview documentation 2015-03-02 10:47:08 +01:00
Lukas Reschke
8c529adf85 Merge pull request #14583 from owncloud/backport-13969
Append search results to custom container
2015-03-01 11:47:22 +01:00
Frank Karlitschek
fb8569499c 8.0.1 2015-02-28 01:03:18 +01:00
Frank Karlitschek
1d9d0f653d this is actually 8.0.1 RC1 2015-02-28 00:54:51 +01:00
Frank Karlitschek
846fdecbcc 8.0.1 RC1
2015-02-28 00:34:48 +01:00
Bernhard Posselt
95cfc4185a Merge pull request #14587 from owncloud/fix/14283
Only read php://input when parameters are requested
2015-02-27 19:52:42 +01:00
Vincent Petry
c78b5453ff Merge pull request #14584 from owncloud/cache-rename-overwrite-stable8
[stable8] Fix cache update when doing a rename that overwrites the target
2015-02-27 18:18:14 +01:00
Lukas Reschke
75cae3b252 Only read php://input when parameters are requested
Less invasive version of https://github.com/owncloud/core/pull/14574 for stable8 as requested at https://github.com/owncloud/core/issues/14283#issuecomment-76402295

Alarm: Major hack detected 🙈
2015-02-27 17:58:18 +01:00
Robin Appelman
a796021143 Fix cache update when doing a rename that overwrites the target 2015-02-27 17:35:28 +01:00
Raimund Schlüßler
83dd98426c Append search results to custom container
* fixes #13968
* fix variable already defined
2015-02-27 17:14:03 +01:00
Thomas Müller
0ec73a58e9 Merge pull request #14579 from owncloud/intuitive-version-check-8
Intuitive version check 8
2015-02-27 07:30:38 -08:00
Bernhard Posselt
d29234382f add phpdoc 2015-02-27 15:23:26 +01:00
Bernhard Posselt
411cd5b2d5 make version check work on the lowest common version denominator 2015-02-27 15:23:22 +01:00
Morris Jobke
6d8d4ea546 Merge pull request #14568 from owncloud/node-check-fileinfo-stable8
[Stable8] Check if we have a proper fileinfo
2015-02-27 15:02:52 +01:00
Joas Schilling
9f6a640e73 Add "throws" lines to calling methods and interface aswell 2015-02-27 12:23:08 +01:00
Robin Appelman
810ac0fca7 Add unit test 2015-02-27 12:22:52 +01:00
Robin Appelman
c77fd2eef6 Check if we have a proper fileinfo 2015-02-27 12:22:37 +01:00
Thomas Müller
3356abe5c7 Merge pull request #14504 from owncloud/stable8-quota-preventdatalossforfailedmove
[stable8] Fix file move/copy when storage space is not enough
2015-02-27 01:08:37 -08:00
Morris Jobke
5faf9f8192 Merge pull request #14533 from owncloud/stable8-defaultvalueforremoteid
[stable8] Add default value for remote_id
2015-02-26 18:37:31 +01:00
Thomas Müller
c8d61ddad8 Merge pull request #14518 from owncloud/backport-14282-stable8
[Backport-14282-stable8]
2015-02-26 08:24:37 -08:00
Vincent Petry
80e3337bad Delete target file for unsuccessful copy/rename 2015-02-26 15:13:52 +01:00
Vincent Petry
17635053ab Bump up files_sharing version for schema update 2015-02-26 15:05:03 +01:00
Robin Appelman
e82f30caae Cleanup garbage collection for global file cache 2015-02-26 14:02:25 +01:00
Thomas Müller
ca7acd8461 Merge pull request #14424 from owncloud/backport-13767
[stable8] Use insertIfNotExists() and reload mimetypes after inserting one
2015-02-26 03:45:13 -08:00
Lukas Reschke
c0550ed953 Merge pull request #14484 from owncloud/backport/auth/14471
[Backport] Always load authentication apps
2015-02-26 12:40:10 +01:00
Vincent Petry
b0a6a54651 Add default value for remote_id
Fixes SQLite migration with non-null column.
2015-02-26 12:06:28 +01:00
Lukas Reschke
b057ae2da1 Merge pull request #14515 from owncloud/stable8-dbal-251
[Stable8] Update doctrine/dbal to 251
2015-02-26 10:28:39 +01:00
Thomas Müller
e277a9b3dd print app upgrade information to console as well 2015-02-25 23:07:48 +01:00
Thomas Müller
5c7157e0af 3rd-party apps are only disabled in case core is upgraded 2015-02-25 23:07:48 +01:00
Thomas Müller
1188c74fe5 shipped and 3rd-party apps of type authentication and session will remain enabled during update 2015-02-25 23:07:48 +01:00
Thomas Müller
06742fe24b 3rd-party apps are disabled on upgrade - refs #14026
Conflicts:
	lib/private/app.php
2015-02-25 23:07:40 +01:00
Victor Dubiniuk
9e38e2c1a9 Skip primary index if the table has one 2015-02-25 23:23:39 +03:00
Victor Dubiniuk
2e361618a3 Update doctrine/dbal to 2.5.1 2015-02-25 23:16:52 +03:00
Thomas Müller
bc14181563 Merge pull request #14491 from owncloud/backport_apostrophe_fix_to_stable8
back port of #14419
2015-02-25 07:05:30 -08:00
Vincent Petry
c6c888c8a1 Properly detect streamCopy errors
Now checking whether the written bytes match the number of read bytes.
2015-02-25 16:04:43 +01:00
Georg Ehrke
5fef637f87 fix issue with previews not being displayed if filename contains apostrophe 2015-02-25 12:21:41 +01:00
Lukas Reschke
2ed3c7af27 Always load authentication apps
The current code path may trigger situations where the LDAP application is not yet loaded and thus problems with the authentication appeared.

In previous versions of ownCloud the authentication mechanism manually loaded these apps which is why this affects ownCloud 8 and master only for my knowledge. (certainly not 6, maybe 7)

Backport to 8 might be something to consider.

Fixes https://github.com/owncloud/core/issues/14469
2015-02-25 10:32:59 +01:00
Thomas Müller
673c8a7531 Merge pull request #14423 from owncloud/backport/14275
Backport/14275
2015-02-23 14:46:35 +01:00
Lukas Reschke
089ad7c242 Merge pull request #14257 from owncloud/backport/14194
[backport-14194-stabe8] URLEncode logout attribute
2015-02-23 14:39:23 +01:00
Joas Schilling
ee83fa673e Use insertIfNotExists() and reload mimetypes after inserting one 2015-02-23 10:44:30 +01:00
Joas Schilling
033635c9fb Merge pull request #14191 from owncloud/bump-random-lib
Bump RandomLib to 1.1.0 for stable8
2015-02-23 10:33:54 +01:00
Christian Seiler
3c51f5ff38 DAV authentication: also use Owncloud's internal user for short-circuit
It still works otherwise, but without this, the performance optimization
of #13416 is defeated in these situations.
2015-02-23 10:25:45 +01:00
Christian Seiler
62029c3541 DAV authentication: use Owncloud's internal user instead of HTTP-supplied one
Fixes: #14048, #14104, calendar#712
2015-02-23 10:25:42 +01:00
Thomas Müller
9735fbb0f4 Merge pull request #14382 from owncloud/backport-14311
[stable8] Fix #14310
2015-02-20 16:16:11 +01:00
Thomas Müller
c8f55ae5dd Merge pull request #14388 from RealRancor/backport_14097_stable8
Backport #14097 (in some case charset can be in lower case)
2015-02-20 16:15:47 +01:00
RealRancor
9e4be2909c in some case charset can be in lower case 2015-02-19 19:53:43 +01:00
Vincent Petry
d8b676f485 Merge pull request #14304 from owncloud/backport/14278
[Stable8 - Backport] Check if the offset exists before accessing
2015-02-19 18:12:14 +01:00
Raimund Schlüßler
08e1ae11d5 Fix #14310 2015-02-19 16:44:48 +01:00
Morris Jobke
88f62bf4ea Merge pull request #14373 from owncloud/fix-nav-s8
Backport #14338 to stable8
2015-02-19 15:15:12 +01:00
Bernhard Posselt
e1985647d5 if no link text has been set for the navigation show the link nonetheless 2015-02-19 13:24:20 +01:00
Thomas Müller
8e55425c93 Merge pull request #14367 from owncloud/remove-old-l10n-files-stable8
[Stable8] Remove old l10n files stable8
2015-02-19 13:04:58 +01:00
Joas Schilling
42c6963acc Remove old l10n files 2015-02-19 12:00:53 +01:00
Thomas Müller
cb3060c940 Merge pull request #14345 from owncloud/stable8-fix-14247
[stable8] Add mapping for a broken varchar type. Fixes #14247
2015-02-18 20:42:45 +01:00
Victor Dubiniuk
cd75ac2e2c Add mapping for a broken varchar type. Fixes #14247 2015-02-18 19:24:13 +03:00
Lukas Reschke
968dc81a74 Merge pull request #14274 from owncloud/backport/14273
[stable8] Use APCu only if available in version 4.0.6 and higher
2015-02-18 01:08:15 +01:00
Lukas Reschke
fc4bb1ae88 Check if the offset exists before accessing
Minified backport of https://github.com/owncloud/core/pull/14278
2015-02-17 17:40:02 +01:00
Lukas Reschke
f4f5097b00 URLEncode logout attribute
Otherwise logout can fail if the requesttoken contains a +
2015-02-17 14:05:50 +01:00
Lukas Reschke
f558ee5802 Use APCu only if available in version 4.0.6 and higher
APCu before 4.0.6 is unbelievable buggy and tend to segfault the PHP process (i.e. the whole webserver)

This potentially fixes https://github.com/owncloud/core/issues/14175

Requires a backport to stable8
2015-02-17 13:28:51 +01:00
Morris Jobke
2740bdc1d9 Merge pull request #14262 from owncloud/fix-last-login-stable8
Return milliseconds instead of seconds for lastLogin - refs #14005
2015-02-16 21:12:33 +01:00
Lukas Reschke
1378c17b55 Merge pull request #14259 from owncloud/fix-autoloader-message-stable8
Properly show the warning about the missing composer autoloader
2015-02-16 20:22:59 +01:00
Thomas Müller
033873c6cc fixing unit tests in UsersControllerTest 2015-02-16 19:45:09 +01:00
Thomas Müller
159d1e4ce7 Return milliseconds instead of seconds for lastLogin - refs #14005 2015-02-16 17:43:13 +01:00
Morris Jobke
5642f1b97a Merge pull request #14258 from owncloud/fix-image-glip-php53-stable8
Check if imageflip is available
2015-02-16 17:35:49 +01:00
Morris Jobke
b25bfb2796 Properly show the warning about the missing composer autoloader 2015-02-16 17:04:21 +01:00
Thomas Müller
4b8d1e8dbd Merge pull request #14019 from owncloud/13925-stable8
no fruitless count attempts, and notification should disappear
2015-02-16 17:01:41 +01:00
Morris Jobke
95aa9a8890 Check if imageflip is available
* imageflip() isn't available in PHP < 5.5
* fixes #14130
2015-02-16 17:01:21 +01:00
Morris Jobke
05e56711f3 Merge pull request #14253 from owncloud/console-execution-time-stable8
[backport-14243-stable8] console commands shall not be limited with respect to execution time
2015-02-16 16:55:13 +01:00
Lukas Reschke
5dd63bdd04 Bump RandomLib to 1.1.0 for stable8
Ref https://github.com/owncloud/3rdparty/pull/160
2015-02-16 16:41:31 +01:00
Thomas Müller
8bd2f2eb23 console commands shall not be limited with respect to execution time - fixes #14156 2015-02-16 15:36:53 +01:00
Lukas Reschke
676c91d4a3 Merge pull request #13987 from owncloud/group-share-collition-wrong-type-in-post-hook-stable8
[stable8] Do not overwrite the shareType so the post hook is still correct
2015-02-16 14:41:46 +01:00
Lukas Reschke
a719f022fb Merge pull request #14198 from owncloud/backport-14086-stable8
[backport-14086-stable8]
2015-02-16 13:41:48 +01:00
Thomas Müller
47ceebbfc5 Merge pull request #14235 from owncloud/typoTurkish
fix typo
2015-02-16 09:52:28 +01:00
Volkan Gezer
ae89229815 Update tr.json 2015-02-15 16:31:12 +01:00
Volkan Gezer
2885a84373 fix typo 2015-02-15 16:30:38 +01:00
RealRancor
def1ffad23 Removed anchor in config.sample.php 2015-02-13 15:28:16 +01:00
Witali Rott
948ee0e398 App install behind a Proxy 2015-02-13 13:32:07 +01:00
Thomas Müller
4e9fd632ea Merge pull request #14168 from owncloud/backport/13771
generate valid human readable text for 0 - fixed #9342
2015-02-13 10:47:44 +01:00
Thomas Müller
cc243e1296 generate valid human readable text for 0 - fixed #9342 2015-02-12 18:35:28 +01:00
Jörn Friedrich Dreyer
d6c7f6f413 Merge pull request #14146 from owncloud/no-whitespace-from-themes-stable8
catch any whitespaces which might get written to the output buffer while...
2015-02-12 17:07:02 +01:00
Thomas Müller
662ebc6c80 catch any whitespaces which might get written to the output buffer while loading a theme 2015-02-12 11:25:01 +01:00
Morris Jobke
4f1f68ead8 Merge pull request #14041 from owncloud/stable8-app-upgrade-order
[Stable 8] app upgrade order
2015-02-12 11:02:19 +01:00
Thomas Müller
ab456bed98 Merge pull request #14080 from owncloud/stable8-preview-hint
Add hint for troubleshooting MS Word previews
2015-02-11 21:17:39 +01:00
RealRancor
4825a4ca1e Add hint for troubleshooting MS Word previews 2015-02-11 01:16:33 +01:00
Vincent Petry
36cb41d15f Fix "other" app update stack 2015-02-10 11:56:51 +01:00
Arthur Schiwon
61eaf0e832 on ownCloud upgrade: upgrade all apps in order, load important ones 2015-02-10 11:56:47 +01:00
Morris Jobke
e95d274f17 Merge pull request #14018 from owncloud/backport-13842
[stable8] check if cache files are readable
2015-02-10 09:32:14 +01:00
Arthur Schiwon
1740fb236e no fruitless count attempts, and notification should disappear 2015-02-10 00:07:55 +01:00
Jörn Friedrich Dreyer
de0c16789e check if cache files are readable
:camel:case

readd is_file
2015-02-09 23:47:56 +01:00
Joas Schilling
f99ca64adc Merge pull request #13983 from owncloud/tempmanager-check-handle-stable8
[stable8] Check directory handle before we use it
2015-02-09 17:06:19 +01:00
Joas Schilling
46186dc896 Add a test for the post_shared hook shareType 2015-02-09 16:24:19 +01:00
Joas Schilling
d0fd28c97c Do not overwrite the shareType so the post hook is still correct 2015-02-09 16:24:04 +01:00
Robin Appelman
c5a87c2a18 Check directory handle before we use it 2015-02-09 16:00:00 +01:00
RealRancor
85d695dbe8 external user app: Add note to enable it first 2015-02-07 20:11:58 +01:00
83 changed files with 1060 additions and 382 deletions

View File

@@ -1,4 +1,4 @@
# Version: 8.0.0
# Version: 8.0.2
<IfModule mod_fcgid.c>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>

View File

@@ -102,7 +102,11 @@ class ApiController extends Controller {
foreach ($fileInfos as &$fileInfo) {
$file = \OCA\Files\Helper::formatFileInfo($fileInfo);
$parts = explode('/', dirname($fileInfo->getPath()), 4);
$file['path'] = '/' . $parts[3];
if(isset($parts[3])) {
$file['path'] = '/' . $parts[3];
} else {
$file['path'] = '/';
}
$file['tags'] = array($tagName);
$files[] = $file;
}

View File

@@ -947,7 +947,7 @@
mime: mime,
etag: fileData.etag,
callback: function(url) {
iconDiv.css('background-image', 'url(' + url + ')');
iconDiv.css('background-image', 'url("' + url + '")');
}
});
}
@@ -959,7 +959,7 @@
};
var previewUrl = this.generatePreviewUrl(urlSpec);
previewUrl = previewUrl.replace('(', '%28').replace(')', '%29');
iconDiv.css('background-image', 'url(' + previewUrl + ')');
iconDiv.css('background-image', 'url("' + previewUrl + '")');
}
}
return tr;

View File

@@ -0,0 +1,243 @@
<?php
/**
* Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files\Controller;
use OC\Files\FileInfo;
use OCP\AppFramework\Http;
use OC\Preview;
use OCP\Files\NotFoundException;
use OCP\Files\StorageNotAvailableException;
use Test\TestCase;
use OCP\IRequest;
use OCA\Files\Service\TagService;
use OCP\AppFramework\Http\DataResponse;
/**
* Class ApiController
*
* @package OCA\Files\Controller
*/
class ApiControllerTest extends TestCase {
/** @var string */
private $appName = 'files';
/** @var IRequest */
private $request;
/** @var TagService */
private $tagService;
/** @var ApiController */
private $apiController;
public function setUp() {
$this->request = $this->getMockBuilder('\OCP\IRequest')
->disableOriginalConstructor()
->getMock();
$this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService')
->disableOriginalConstructor()
->getMock();
$this->apiController = new ApiController(
$this->appName,
$this->request,
$this->tagService
);
}
public function testGetFilesByTagEmpty() {
$tagName = 'MyTagName';
$this->tagService->expects($this->once())
->method('getFilesByTag')
->with($this->equalTo([$tagName]))
->will($this->returnValue([]));
$expected = new DataResponse(['files' => []]);
$this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName]));
}
public function testGetFilesByTagSingle() {
$tagName = 'MyTagName';
$fileInfo = new FileInfo(
'/root.txt',
$this->getMockBuilder('\OC\Files\Storage\Storage')
->disableOriginalConstructor()
->getMock(),
'/var/www/root.txt',
[
'mtime' => 55,
'mimetype' => 'application/pdf',
'size' => 1234,
'etag' => 'MyEtag',
],
$this->getMockBuilder('\OCP\Files\Mount\IMountPoint')
->disableOriginalConstructor()
->getMock()
);
$this->tagService->expects($this->once())
->method('getFilesByTag')
->with($this->equalTo([$tagName]))
->will($this->returnValue([$fileInfo]));
$expected = new DataResponse([
'files' => [
[
'id' => null,
'parentId' => null,
'date' => 'January 1, 1970 at 12:00:55 AM GMT+0',
'mtime' => 55000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo),
'name' => 'root.txt',
'permissions' => null,
'mimetype' => 'application/pdf',
'size' => 1234,
'type' => 'file',
'etag' => 'MyEtag',
'path' => '/',
'tags' => [
[
'MyTagName'
]
],
],
],
]);
$this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName]));
}
public function testGetFilesByTagMultiple() {
$tagName = 'MyTagName';
$fileInfo1 = new FileInfo(
'/root.txt',
$this->getMockBuilder('\OC\Files\Storage\Storage')
->disableOriginalConstructor()
->getMock(),
'/var/www/root.txt',
[
'mtime' => 55,
'mimetype' => 'application/pdf',
'size' => 1234,
'etag' => 'MyEtag',
],
$this->getMockBuilder('\OCP\Files\Mount\IMountPoint')
->disableOriginalConstructor()
->getMock()
);
$fileInfo2 = new FileInfo(
'/root.txt',
$this->getMockBuilder('\OC\Files\Storage\Storage')
->disableOriginalConstructor()
->getMock(),
'/var/www/some/sub.txt',
[
'mtime' => 999,
'mimetype' => 'application/binary',
'size' => 9876,
'etag' => 'SubEtag',
],
$this->getMockBuilder('\OCP\Files\Mount\IMountPoint')
->disableOriginalConstructor()
->getMock()
);
$this->tagService->expects($this->once())
->method('getFilesByTag')
->with($this->equalTo([$tagName]))
->will($this->returnValue([$fileInfo1, $fileInfo2]));
$expected = new DataResponse([
'files' => [
[
'id' => null,
'parentId' => null,
'date' => 'January 1, 1970 at 12:00:55 AM GMT+0',
'mtime' => 55000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo1),
'name' => 'root.txt',
'permissions' => null,
'mimetype' => 'application/pdf',
'size' => 1234,
'type' => 'file',
'etag' => 'MyEtag',
'path' => '/',
'tags' => [
[
'MyTagName'
]
],
],
[
'id' => null,
'parentId' => null,
'date' => 'January 1, 1970 at 12:16:39 AM GMT+0',
'mtime' => 999000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo2),
'name' => 'root.txt',
'permissions' => null,
'mimetype' => 'application/binary',
'size' => 9876,
'type' => 'file',
'etag' => 'SubEtag',
'path' => '/',
'tags' => [
[
'MyTagName'
]
],
]
],
]);
$this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName]));
}
public function testUpdateFileTagsEmpty() {
$expected = new DataResponse([]);
$this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt'));
}
public function testUpdateFileTagsWorking() {
$this->tagService->expects($this->once())
->method('updateFileTags')
->with('/path.txt', ['Tag1', 'Tag2']);
$expected = new DataResponse([
'tags' => [
'Tag1',
'Tag2'
],
]);
$this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2']));
}
public function testUpdateFileTagsNotFoundException() {
$this->tagService->expects($this->once())
->method('updateFileTags')
->with('/path.txt', ['Tag1', 'Tag2'])
->will($this->throwException(new NotFoundException('My error message')));
$expected = new DataResponse('My error message', Http::STATUS_NOT_FOUND);
$this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2']));
}
public function testUpdateFileTagsStorageNotAvailableException() {
$this->tagService->expects($this->once())
->method('updateFileTags')
->with('/path.txt', ['Tag1', 'Tag2'])
->will($this->throwException(new StorageNotAvailableException('My error message')));
$expected = new DataResponse('My error message', Http::STATUS_SERVICE_UNAVAILABLE);
$this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2']));
}
public function testUpdateFileTagsStorageGenericException() {
$this->tagService->expects($this->once())
->method('updateFileTags')
->with('/path.txt', ['Tag1', 'Tag2'])
->will($this->throwException(new \Exception('My error message')));
$expected = new DataResponse('My error message', Http::STATUS_NOT_FOUND);
$this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2']));
}
}

View File

@@ -1,5 +0,0 @@
<?php
$TRANSLATIONS = array(
"Saving..." => "Spašavam..."
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";

View File

@@ -1,5 +0,0 @@
<?php
$TRANSLATIONS = array(
"Saving..." => "Simpan..."
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@@ -1,5 +0,0 @@
<?php
$TRANSLATIONS = array(
"Saving..." => "Enregistra..."
);
$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";

View File

@@ -1,5 +0,0 @@
<?php
$TRANSLATIONS = array(
"personal settings" => "వ్యక్తిగత అమరికలు"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -25,6 +25,7 @@
<field>
<name>remote_id</name>
<type>integer</type>
<default>-1</default>
<notnull>true</notnull>
<length>4</length>
</field>

View File

@@ -1 +1 @@
0.6.0
0.6.1

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array(""),
"_%n file_::_%n files_" => array("")
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array(""),
"_%n file_::_%n files_" => array("")
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array(""),
"_%n file_::_%n files_" => array("")
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -1,5 +0,0 @@
<?php $TRANSLATIONS = array(
"History" => "Historique",
"Files Versioning" => "Fichier's Versionéierung ",
"Enable" => "Aschalten"
);

View File

@@ -85,7 +85,7 @@ switch($action) {
exit;
}
} catch (\Exception $e) {
\OCP\JSON::error(array('message' => $e->getMessage()));
\OCP\JSON::error(array('message' => $e->getMessage(), 'code' => $e->getCode()));
exit;
}
\OCP\JSON::error();

View File

@@ -351,7 +351,7 @@ var LdapWizard = {
encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner(spinnerID);
var request = LdapWizard.ajax(param,
LdapWizard.ajax(param,
function(result) {
LdapWizard.applyChanges(result);
LdapWizard.hideSpinner(spinnerID);
@@ -360,7 +360,7 @@ var LdapWizard = {
}
},
function (result) {
OC.Notification.show('Counting the entries failed with, ' + result.message);
OC.Notification.showTemporary('Counting the entries failed with: ' + result.message);
LdapWizard.hideSpinner(spinnerID);
if(!_.isUndefined(doneCallback)) {
doneCallback(method);
@@ -371,11 +371,17 @@ var LdapWizard = {
},
countGroups: function(doneCallback) {
LdapWizard._countThings('countGroups', '#ldap_group_count', doneCallback);
var groupFilter = $('#ldap_group_filter').val();
if(!_.isEmpty(groupFilter)) {
LdapWizard._countThings('countGroups', '#ldap_group_count', doneCallback);
}
},
countUsers: function(doneCallback) {
LdapWizard._countThings('countUsers', '#ldap_user_count', doneCallback);
var userFilter = $('#ldap_userlist_filter').val();
if(!_.isEmpty(userFilter)) {
LdapWizard._countThings('countUsers', '#ldap_user_count', doneCallback);
}
},
/**

View File

@@ -1,6 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%s group found_::_%s groups found_" => array("",""),
"_%s user found_::_%s users found_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -229,9 +229,9 @@ $CONFIG = array(
'skeletondirectory' => '',
/**
* The ``user_backends`` app allows you to configure alternate authentication
* backends. Supported backends are IMAP (OC_User_IMAP), SMB (OC_User_SMB), and
* FTP (OC_User_FTP).
* The ``user_backends`` app (which needs to be enabled first) allows you to
* configure alternate authentication backends. Supported backends are:
* IMAP (OC_User_IMAP), SMB (OC_User_SMB), and FTP (OC_User_FTP).
*/
'user_backends' => array(
array(
@@ -669,6 +669,10 @@ $CONFIG = array(
* - OC\Preview\StarOffice
* - OC\Preview\SVG
* - OC\Preview\TIFF
*
* .. note:: Troubleshooting steps for the MS Word previews are available
* at the :doc:`../configuration_files/collaborative_documents_configuration`
* section of the Administrators Manual.
*
* The following providers are not available in Microsoft Windows:
*

View File

@@ -11,6 +11,9 @@ use Symfony\Component\Console\Application;
try {
require_once 'lib/base.php';
// set to run indefinitely if needed
set_time_limit(0);
// Don't do anything if ownCloud has not been installed yet
if (!\OC::$server->getConfig()->getSystemValue('installed', false)) {
echo "Console can only be used once ownCloud has been installed" . PHP_EOL;

View File

@@ -11,9 +11,12 @@ if (OC::checkUpgrade(false)) {
$eventSource = \OC::$server->createEventSource();
$updater = new \OC\Updater(
\OC::$server->getHTTPHelper(),
\OC::$server->getAppConfig(),
\OC::$server->getConfig(),
\OC_Log::$object
);
$incompatibleApps = [];
$disabledThirdPartyApps = [];
$updater->listen('\OC\Updater', 'maintenanceStart', function () use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Turned on maintenance mode'));
});
@@ -32,13 +35,11 @@ if (OC::checkUpgrade(false)) {
$updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Updated "%s" to %s', array($app, $version)));
});
$updater->listen('\OC\Updater', 'disabledApps', function ($appList) use ($eventSource, $l) {
$list = array();
foreach ($appList as $appId) {
$info = OC_App::getAppInfo($appId);
$list[] = $info['name'] . ' (' . $info['id'] . ')';
}
$eventSource->send('success', (string)$l->t('Disabled incompatible apps: %s', implode(', ', $list)));
$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use (&$incompatibleApps) {
$incompatibleApps[]= $app;
});
$updater->listen('\OC\Updater', 'thirdPartyAppDisabled', function ($app) use (&$disabledThirdPartyApps) {
$disabledThirdPartyApps[]= $app;
});
$updater->listen('\OC\Updater', 'failure', function ($message) use ($eventSource) {
$eventSource->send('failure', $message);
@@ -48,6 +49,15 @@ if (OC::checkUpgrade(false)) {
$updater->upgrade();
if (!empty($incompatibleApps)) {
$eventSource->send('notice',
(string)$l->t('Following incompatible apps have been disabled: %s', implode(', ', $incompatibleApps)));
}
if (!empty($disabledThirdPartyApps)) {
$eventSource->send('notice',
(string)$l->t('Following 3rd party apps have been disabled: %s', implode(', ', $disabledThirdPartyApps)));
}
$eventSource->send('done', '');
$eventSource->close();
}

View File

@@ -84,7 +84,8 @@ class Upgrade extends Command {
if(\OC::checkUpgrade(false)) {
$self = $this;
$updater = new Updater(\OC::$server->getHTTPHelper(), \OC::$server->getAppConfig());
$updater = new Updater(\OC::$server->getHTTPHelper(),
\OC::$server->getConfig());
$updater->setSimulateStepEnabled($simulateStepEnabled);
$updater->setUpdateStepEnabled($updateStepEnabled);
@@ -106,8 +107,17 @@ class Upgrade extends Command {
$updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use($output) {
$output->writeln('<info>Checked database schema update</info>');
});
$updater->listen('\OC\Updater', 'disabledApps', function ($appList) use($output) {
$output->writeln('<info>Disabled incompatible apps: ' . implode(', ', $appList) . '</info>');
$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use($output) {
$output->writeln('<info>Disabled incompatible app: ' . $app . '</info>');
});
$updater->listen('\OC\Updater', 'thirdPartyAppDisabled', function ($app) use($output) {
$output->writeln('<info>Disabled 3rd-party app: ' . $app . '</info>');
});
$updater->listen('\OC\Updater', 'appUpgradeCheck', function () use ($output) {
$output->writeln('<info>Checked database schema update for apps</info>');
});
$updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($output) {
$output->writeln("<info>Updated <$app> to $version</info>");
});
$updater->listen('\OC\Updater', 'failure', function ($message) use($output, $self) {

View File

@@ -74,6 +74,7 @@
display: block;
width: 100%;
line-height: 44px;
min-height: 44px;
padding: 0 12px;
overflow: hidden;
-moz-box-sizing: border-box; box-sizing: border-box;

View File

@@ -1213,7 +1213,7 @@ $.fn.filterAttr = function(attr_name, attr_value) {
function humanFileSize(size, skipSmallSizes) {
var humanList = ['B', 'kB', 'MB', 'GB', 'TB'];
// Calculate Log with base 1024: size = 1024 ** order
var order = size?Math.floor(Math.log(size) / Math.log(1024)):0;
var order = size > 0 ? Math.floor(Math.log(size) / Math.log(1024)) : 0;
// Stay in range of the byte sizes that are defined
order = Math.min(humanList.length - 1, order);
var readableFormat = humanList[order];

View File

@@ -465,6 +465,8 @@ describe('Core base tests', function() {
it('renders file sizes with the correct unit', function() {
var data = [
[0, '0 B'],
["0", '0 B'],
["A", 'NaN B'],
[125, '125 B'],
[128000, '125 kB'],
[128000000, '122.1 MB'],

View File

@@ -38,6 +38,9 @@
updateEventSource.listen('success', function(message) {
$('<span>').append(message).append('<br />').appendTo($el);
});
updateEventSource.listen('notice', function(message) {
$('<span>').addClass('error').append(message).append('<br />').appendTo($el);
});
updateEventSource.listen('error', function(message) {
$('<span>').addClass('error').append(message).append('<br />').appendTo($el);
message = t('core', 'Please reload the page.');

View File

@@ -1,9 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n minute ago_::_%n minutes ago_" => array("",""),
"_%n hour ago_::_%n hours ago_" => array("",""),
"_%n day ago_::_%n days ago_" => array("",""),
"_%n month ago_::_%n months ago_" => array("",""),
"_{count} file conflict_::_{count} file conflicts_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -337,7 +337,7 @@
var $row = $(this);
var item = $row.data('result');
if(self.hasHandler(item.type)){
var result = self.getHandler(item.type)($row, result, event);
var result = self.getHandler(item.type)($row, item, event);
$searchBox.val('');
if(self.hasFilter(getCurrentApp())) {
self.getFilter(getCurrentApp())('');
@@ -360,10 +360,17 @@
})();
$(document).ready(function() {
var $searchResults = $('<div id="searchresults" class="hidden"/>');
$('#app-content')
.append($searchResults)
.find('.viewcontainer').css('min-height', 'initial');
var $searchResults = $('#searchresults');
if ($searchResults.length) {
$searchResults.addClass('hidden');
$('#app-content')
.find('.viewcontainer').css('min-height', 'initial');
} else {
$searchResults = $('<div id="searchresults" class="hidden"/>');
$('#app-content')
.append($searchResults)
.find('.viewcontainer').css('min-height', 'initial');
}
$searchResults.load(OC.webroot + '/core/search/templates/part.results.html', function () {
OC.Search = new OCA.Search($('#searchbox'), $('#searchresults'));
});

View File

@@ -478,7 +478,10 @@ class OC {
require_once $vendorAutoLoad;
} else {
OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
OC_Template::printErrorPage('Composer autoloader not found, unable to continue.');
// we can't use the template error page here, because this needs the
// DI container which isn't available yet
print('Composer autoloader not found, unable to continue. Check the folder "3rdparty".');
exit();
}
// setup the basic server
@@ -736,6 +739,9 @@ class OC {
self::checkUpgrade();
}
// Always load authentication apps
OC_App::loadApps(['authentication']);
// Load minimum set of apps
if (!self::checkUpgrade(false)
&& !$systemConfig->getValue('maintenance', false)
@@ -744,8 +750,7 @@ class OC {
if(OC_User::isLoggedIn()) {
OC_App::loadApps();
} else {
// For guests: Load only authentication, filesystem and logging
OC_App::loadApps(array('authentication'));
// For guests: Load only filesystem and logging
OC_App::loadApps(array('filesystem', 'logging'));
\OC_User::tryBasicAuthLogin();
}
@@ -754,7 +759,6 @@ class OC {
if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) {
try {
if (!$systemConfig->getValue('maintenance', false) && !\OCP\Util::needUpgrade()) {
OC_App::loadApps(array('authentication'));
OC_App::loadApps(array('filesystem', 'logging'));
OC_App::loadApps();
}

View File

@@ -1,8 +0,0 @@
<?php
$TRANSLATIONS = array(
"_%n minute ago_::_%n minutes ago_" => array("",""),
"_%n hour ago_::_%n hours ago_" => array("",""),
"_%n day go_::_%n days ago_" => array("",""),
"_%n month ago_::_%n months ago_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@@ -161,7 +161,6 @@ class AllConfig implements \OCP\IConfig {
\OC::$server->getAppConfig()->deleteApp($appName);
}
/**
* Set a user defined value
*

View File

@@ -277,6 +277,7 @@ class OC_App {
*/
public static function enable($app, $groups = null) {
self::$enabledAppsCache = array(); // flush
if (!OC_Installer::isInstalled($app)) {
$app = self::installApp($app);
}
@@ -327,6 +328,12 @@ class OC_App {
self::$enabledAppsCache = array(); // flush
// check if app is a shipped app or not. if not delete
\OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
// Convert OCS ID to regular application identifier
if(self::getInternalAppIdByOcs($app) !== false) {
$app = self::getInternalAppIdByOcs($app);
}
OC_Appconfig::setValue($app, 'enabled', 'no' );
}
@@ -896,6 +903,21 @@ class OC_App {
return $combinedApps;
}
/**
* Returns the internal app ID or false
* @param string $ocsID
* @return string|false
*/
protected static function getInternalAppIdByOcs($ocsID) {
if(is_numeric($ocsID)) {
$idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
if(array_search($ocsID, $idArray)) {
return array_search($ocsID, $idArray);
}
}
return false;
}
/**
* get a list of all apps on apps.owncloud.com
* @return array, multi-dimensional array of apps.
@@ -921,11 +943,13 @@ class OC_App {
$i = 0;
$l = \OC::$server->getL10N('core');
foreach ($remoteApps as $app) {
$potentialCleanId = self::getInternalAppIdByOcs($app['id']);
// enhance app info (for example the description)
$app1[$i] = OC_App::parseAppInfo($app);
$app1[$i]['author'] = $app['personid'];
$app1[$i]['ocs_id'] = $app['id'];
$app1[$i]['internal'] = $app1[$i]['active'] = 0;
$app1[$i]['internal'] = 0;
$app1[$i]['active'] = ($potentialCleanId !== false) ? self::isEnabled($potentialCleanId) : false;
$app1[$i]['update'] = false;
$app1[$i]['groups'] = false;
$app1[$i]['score'] = $app['score'];
@@ -957,39 +981,6 @@ class OC_App {
return false;
}
/**
* check if the current enabled apps are compatible with the current
* ownCloud version. disable them if not.
* This is important if you upgrade ownCloud and have non ported 3rd
* party apps installed.
*
* @param array $apps optional app id list to check, uses all enabled apps
* when not specified
*
* @return array containing the list of ids of the disabled apps
*/
public static function checkAppsRequirements($apps = array()) {
$disabledApps = array();
if (empty($apps)) {
$apps = OC_App::getEnabledApps();
}
$version = OC_Util::getVersion();
foreach ($apps as $app) {
// check if the app is compatible with this version of ownCloud
$info = OC_App::getAppInfo($app);
if(!self::isAppCompatible($version, $info)) {
OC_Log::write('core',
'App "' . $info['name'] . '" (' . $app . ') can\'t be used because it is'
. ' not compatible with this version of ownCloud',
OC_Log::ERROR);
OC_App::disable($app);
OC_Hook::emit('update', 'success', 'Disabled ' . $info['name'] . ' app because it is not compatible');
$disabledApps[] = $app;
}
}
return $disabledApps;
}
/**
* Adjust the number of version parts of $version1 to match
* the number of version parts of $version2.
@@ -1088,7 +1079,6 @@ class OC_App {
}
}
/**
* @param mixed $app
* @return bool
@@ -1108,8 +1098,21 @@ class OC_App {
} else {
$app = OC_Installer::installShippedApp($app);
}
}else{
$app = self::downloadApp($app);
} else {
// Maybe the app is already installed - compare the version in this
// case and use the local already installed one.
// FIXME: This is a horrible hack. I feel sad. The god of code cleanness may forgive me.
$internalAppId = self::getInternalAppIdByOcs($app);
if($internalAppId !== false) {
if($appData && version_compare(\OC_App::getAppVersion($internalAppId), $appData['version'], '<')) {
$app = self::downloadApp($app);
} else {
self::enable($internalAppId);
$app = $internalAppId;
}
} else {
$app = self::downloadApp($app);
}
}
if($app!==false) {

View File

@@ -50,17 +50,77 @@ class DependencyAnalyzer {
$this->analyzeOC($dependencies, $app));
}
/**
* Truncates both verions to the lowest common version, e.g.
* 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
* 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
* @param string $first
* @param string $second
* @return array first element is the first version, second element is the
* second version
*/
private function normalizeVersions($first, $second) {
$first = explode('.', $first);
$second = explode('.', $second);
// get both arrays to the same minimum size
$length = min(count($second), count($first));
$first = array_slice($first, 0, $length);
$second = array_slice($second, 0, $length);
return [implode('.', $first), implode('.', $second)];
}
/**
* Parameters will be normalized and then passed into version_compare
* in the same order they are specified in the method header
* @param string $first
* @param string $second
* @param string $operator
* @return bool result similar to version_compare
*/
private function compare($first, $second, $operator) {
// we cant normalize versions if one of the given parameters is not a
// version string but null. In case one parameter is null normalization
// will therefore be skipped
if ($first !== null && $second !== null) {
list($first, $second) = $this->normalizeVersions($first, $second);
}
return version_compare($first, $second, $operator);
}
/**
* Checks if a version is bigger than another version
* @param string $first
* @param string $second
* @return bool true if the first version is bigger than the second
*/
private function compareBigger($first, $second) {
return $this->compare($first, $second, '>');
}
/**
* Checks if a version is smaller than another version
* @param string $first
* @param string $second
* @return bool true if the first version is smaller than the second
*/
private function compareSmaller($first, $second) {
return $this->compare($first, $second, '<');
}
private function analyzePhpVersion($dependencies) {
$missing = [];
if (isset($dependencies['php']['@attributes']['min-version'])) {
$minVersion = $dependencies['php']['@attributes']['min-version'];
if (version_compare($this->platform->getPhpVersion(), $minVersion, '<')) {
if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
$missing[] = (string)$this->l->t('PHP %s or higher is required.', $minVersion);
}
}
if (isset($dependencies['php']['@attributes']['max-version'])) {
$maxVersion = $dependencies['php']['@attributes']['max-version'];
if (version_compare($this->platform->getPhpVersion(), $maxVersion, '>')) {
if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
$missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', $maxVersion);
}
}
@@ -134,14 +194,14 @@ class DependencyAnalyzer {
if (is_array($lib)) {
if (isset($lib['@attributes']['min-version'])) {
$minVersion = $lib['@attributes']['min-version'];
if (version_compare($libVersion, $minVersion, '<')) {
if ($this->compareSmaller($libVersion, $minVersion)) {
$missing[] = (string)$this->l->t('Library %s with a version higher than %s is required - available version %s.',
array($libName, $minVersion, $libVersion));
}
}
if (isset($lib['@attributes']['max-version'])) {
$maxVersion = $lib['@attributes']['max-version'];
if (version_compare($libVersion, $maxVersion, '>')) {
if ($this->compareBigger($libVersion, $maxVersion)) {
$missing[] = (string)$this->l->t('Library %s with a version lower than %s is required - available version %s.',
array($libName, $maxVersion, $libVersion));
}
@@ -193,12 +253,12 @@ class DependencyAnalyzer {
}
if (!is_null($minVersion)) {
if (version_compare($this->platform->getOcVersion(), $minVersion, '<')) {
if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
$missing[] = (string)$this->l->t('ownCloud %s or higher is required.', $minVersion);
}
}
if (!is_null($maxVersion)) {
if (version_compare($this->platform->getOcVersion(), $maxVersion, '>')) {
if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
$missing[] = (string)$this->l->t('ownCloud with a version lower than %s is required.', $maxVersion);
}
}

View File

@@ -48,6 +48,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
'method',
'requesttoken',
);
protected $streamReadInitialized = false;
/**
* @param array $vars An associative array with the following optional values:
@@ -86,16 +87,6 @@ class Request implements \ArrayAccess, \Countable, IRequest {
$this->items['post'] = $params;
}
}
// Handle application/x-www-form-urlencoded for methods other than GET
// or post correctly
} elseif($vars['method'] !== 'GET'
&& $vars['method'] !== 'POST'
&& strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
parse_str(file_get_contents($this->inputStream), $params);
if(is_array($params)) {
$this->items['params'] = $params;
}
}
$this->items['parameters'] = array_merge(
@@ -276,6 +267,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return mixed the content of the array
*/
public function getParam($key, $default = null) {
$this->initializeStreamParams();
return isset($this->parameters[$key])
? $this->parameters[$key]
: $default;
@@ -287,9 +279,35 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return array the array with all parameters
*/
public function getParams() {
$this->initializeStreamParams();
return $this->parameters;
}
/**
* Workaround for ownCloud 8 to only read the stream-input when parameters
* are requested. For the next master release this is removed and implemented
* using a different approach.
*/
protected function initializeStreamParams() {
if(
$this->streamReadInitialized === false &&
$this->getMethod() !== 'GET' &&
$this->getMethod() !== 'POST' &&
strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false
) {
$params = [];
parse_str(file_get_contents($this->inputStream), $params);
if(!empty($params)) {
$this->items['params'] = $params;
$this->items['parameters'] = array_merge(
$this->items['parameters'],
$this->items['params']
);
}
}
$this->streamReadInitialized = true;
}
/**
* Returns the method of the request
* @return string the method of the request (POST, GET, etc)
@@ -337,6 +355,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @throws \LogicException
*/
protected function getContent() {
$this->initializeStreamParams();
// If the content can't be parsed into an array then return a stream resource.
if ($this->method === 'PUT'
&& strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false

View File

@@ -83,7 +83,7 @@ class File {
public function hasKey($key) {
$storage = $this->getStorage();
if ($storage && $storage->is_file($key)) {
if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
return true;
}
return false;

View File

@@ -52,7 +52,7 @@ class FileGlobal {
public function hasKey($key) {
$key = $this->fixKey($key);
$cache_dir = self::getCacheDir();
if ($cache_dir && is_file($cache_dir.$key)) {
if ($cache_dir && is_file($cache_dir.$key) && is_readable($cache_dir.$key)) {
$mtime = filemtime($cache_dir.$key);
if ($mtime < time()) {
unlink($cache_dir.$key);
@@ -86,29 +86,4 @@ class FileGlobal {
}
}
}
static public function gc() {
$appConfig = \OC::$server->getAppConfig();
$last_run = $appConfig->getValue('core', 'global_cache_gc_lastrun', 0);
$now = time();
if (($now - $last_run) < 300) {
// only do cleanup every 5 minutes
return;
}
$appConfig->setValue('core', 'global_cache_gc_lastrun', $now);
$cache_dir = self::getCacheDir();
if($cache_dir and is_dir($cache_dir)) {
$dh=opendir($cache_dir);
if(is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if($file!='.' and $file!='..') {
$mtime = filemtime($cache_dir.$file);
if ($mtime < $now) {
unlink($cache_dir.$file);
}
}
}
}
}
}
}

View File

@@ -2,8 +2,51 @@
namespace OC\Cache;
class FileGlobalGC extends \OC\BackgroundJob\Job{
public function run($argument){
FileGlobal::gc();
use OC\BackgroundJob\Job;
use OCP\IConfig;
class FileGlobalGC extends Job {
public function run($argument) {
$this->gc(\OC::$server->getConfig(), $this->getCacheDir());
}
protected function getCacheDir() {
return get_temp_dir() . '/owncloud-' . \OC_Util::getInstanceId() . '/';
}
/**
* @param string $cacheDir
* @param int $now
* @return string[]
*/
public function getExpiredPaths($cacheDir, $now) {
$files = scandir($cacheDir);
$files = array_filter($files, function ($file) {
return $file != '.' and $file != '..';
});
$paths = array_map(function ($file) use ($cacheDir) {
return $cacheDir . $file;
}, $files);
return array_values(array_filter($paths, function ($path) use ($now) {
return is_file($path) and (filemtime($path) < $now);
}));
}
/**
* @param \OCP\IConfig $config
* @param string $cacheDir
*/
public function gc(IConfig $config, $cacheDir) {
$lastRun = $config->getAppValue('core', 'global_cache_gc_lastrun', 0);
$now = time();
if (($now - $lastRun) < 300) {
// only do cleanup every 5 minutes
return;
}
$config->setAppValue('core', 'global_cache_gc_lastrun', $now);
if (!is_dir($cacheDir)) {
return;
}
array_walk($this->getExpiredPaths($cacheDir, $now), 'unlink');
}
}

View File

@@ -52,7 +52,7 @@ class OC_Connector_Sabre_Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
*/
protected function validateUserPass($username, $password) {
if (OC_User::isLoggedIn() &&
$this->isDavAuthenticated($username)
$this->isDavAuthenticated(OC_User::getUser())
) {
OC_Util::setupFS(OC_User::getUser());
\OC::$server->getSession()->close();
@@ -60,8 +60,11 @@ class OC_Connector_Sabre_Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
} else {
OC_Util::setUpFS(); //login hooks may need early access to the filesystem
if(OC_User::login($username, $password)) {
OC_Util::setUpFS(OC_User::getUser());
\OC::$server->getSession()->set(self::DAV_AUTHENTICATED, $username);
// make sure we use owncloud's internal username here
// and not the HTTP auth supplied one, see issue #14048
$ocUser = OC_User::getUser();
OC_Util::setUpFS($ocUser);
\OC::$server->getSession()->set(self::DAV_AUTHENTICATED, $ocUser);
\OC::$server->getSession()->close();
return true;
} else {

View File

@@ -19,11 +19,13 @@ class AdapterSqlite extends Adapter {
}
public function insertIfNotExist($table, $input) {
// NOTE: For SQLite we have to use this clumsy approach
// otherwise all fieldnames used must have a unique key.
$query = 'SELECT COUNT(*) FROM `' . $table . '` WHERE ';
$inserts = array();
foreach ($input as $key => $value) {
$fieldList = '`' . implode('`,`', array_keys($input)) . '`';
$query = "INSERT INTO `$table` ($fieldList) SELECT "
. str_repeat('?,', count($input)-1).'? '
. " WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE ";
$inserts = array_values($input);
foreach($input as $key => $value) {
$query .= '`' . $key . '`';
if (is_null($value)) {
$query .= ' IS NULL AND ';
@@ -33,34 +35,10 @@ class AdapterSqlite extends Adapter {
}
}
$query = substr($query, 0, strlen($query) - 5);
$query .= ')';
try {
$stmt = $this->conn->prepare($query);
$result = $stmt->execute($inserts);
} catch(\Doctrine\DBAL\DBALException $e) {
$entry = 'DB Error: "'.$e->getMessage() . '"<br />';
$entry .= 'Offending command was: ' . $query . '<br />';
\OC_Log::write('core', $entry, \OC_Log::FATAL);
$l = \OC::$server->getL10N('lib');
throw new \OC\HintException(
$l->t('Database Error'),
$l->t('Please contact your system administrator.'),
0,
$e
);
}
if ($stmt->fetchColumn() === '0') {
$query = 'INSERT INTO `' . $table . '` (`'
. implode('`,`', array_keys($input)) . '`) VALUES('
. str_repeat('?,', count($input)-1).'? ' . ')';
} else {
return 0; //no rows updated
}
try {
$statement = $this->conn->prepare($query);
$result = $statement->execute(array_values($input));
return $this->conn->executeUpdate($query, $inserts);
} catch(\Doctrine\DBAL\DBALException $e) {
$entry = 'DB Error: "'.$e->getMessage() . '"<br />';
$entry .= 'Offending command was: ' . $query.'<br />';
@@ -73,7 +51,5 @@ class AdapterSqlite extends Adapter {
$e
);
}
return $result;
}
}

View File

@@ -293,6 +293,9 @@ class MDB2SchemaReader {
}
if (!empty($fields)) {
if (isset($primary) && $primary) {
if ($table->hasPrimaryKey()) {
return;
}
$table->setPrimaryKey($fields, $name);
} else {
if (isset($unique) && $unique) {

View File

@@ -58,6 +58,7 @@ class SQLiteMigrator extends Migrator {
$platform = $connection->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('tinyint unsigned', 'integer');
$platform->registerDoctrineTypeMapping('smallint unsigned', 'integer');
$platform->registerDoctrineTypeMapping('varchar ', 'string');
return parent::getDiff($targetSchema, $connection);
}

View File

@@ -1,9 +1,5 @@
<?php
if (file_exists(OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults.php')) {
require_once 'themes/' . OC_Util::getTheme() . '/defaults.php';
}
/**
* Default strings and values which differ between the enterprise and the
* community edition. Use the get methods to always get the right strings.
@@ -45,7 +41,11 @@ class OC_Defaults {
$this->defaultLogoClaim = '';
$this->defaultMailHeaderColor = '#1d2d44'; /* header color of mail notifications */
if (class_exists('OC_Theme')) {
if (file_exists(OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults.php')) {
// prevent defaults.php from printing output
ob_start();
require_once 'themes/' . OC_Util::getTheme() . '/defaults.php';
ob_end_clean();
$this->theme = new OC_Theme();
}
}

View File

@@ -74,9 +74,11 @@ class Cache {
if (!isset(self::$mimetypeIds[$mime])) {
try {
$result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime));
self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes');
self::$mimetypes[self::$mimetypeIds[$mime]] = $mime;
$connection = \OC_DB::getConnection();
$connection->insertIfNotExist('*PREFIX*mimetypes', [
'mimetype' => $mime,
]);
$this->loadMimetypes();
} catch (\Doctrine\DBAL\DBALException $e) {
\OC_Log::write('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OC_Log::DEBUG);
return -1;
@@ -95,6 +97,8 @@ class Cache {
}
public function loadMimetypes() {
self::$mimetypeIds = self::$mimetypes = array();
$result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array());
if ($result) {
while ($row = $result->fetchRow()) {
@@ -236,13 +240,19 @@ class Cache {
list($queryParts, $params) = $this->buildParts($data);
$queryParts[] = '`storage`';
$params[] = $this->getNumericStorageId();
$valuesPlaceholder = array_fill(0, count($queryParts), '?');
$sql = 'INSERT INTO `*PREFIX*filecache` (' . implode(', ', $queryParts) . ')'
. ' VALUES (' . implode(', ', $valuesPlaceholder) . ')';
\OC_DB::executeAudited($sql, $params);
$params = array_map(function($item) {
return trim($item, "`");
}, $params);
$queryParts = array_map(function($item) {
return trim($item, "`");
}, $queryParts);
$values = array_combine($queryParts, $params);
if (\OC::$server->getDatabaseConnection()->insertIfNotExist('*PREFIX*filecache', $values)) {
return (int)\OC_DB::insertid('*PREFIX*filecache');
}
return (int)\OC_DB::insertid('*PREFIX*filecache');
return $this->getId($file);
}
}

View File

@@ -42,6 +42,9 @@ class Updater {
* @param int $time
*/
public function update($path, $time = null) {
if (Scanner::isPartialFile($path)) {
return;
}
/**
* @var \OC\Files\Storage\Storage $storage
* @var string $internalPath
@@ -104,6 +107,9 @@ class Updater {
if ($sourceStorage && $targetStorage) {
if ($sourceStorage === $targetStorage) {
$cache = $sourceStorage->getCache($sourceInternalPath);
if ($cache->inCache($targetInternalPath)) {
$cache->remove($targetInternalPath);
}
$cache->move($sourceInternalPath, $targetInternalPath);
if (pathinfo($sourceInternalPath, PATHINFO_EXTENSION) !== pathinfo($targetInternalPath, PATHINFO_EXTENSION)) {

View File

@@ -8,6 +8,10 @@
namespace OC\Files\Node;
use OC\Files\Filesystem;
use OCP\Files\FileInfo;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
class Node implements \OCP\Files\Node {
@@ -45,11 +49,21 @@ class Node implements \OCP\Files\Node {
/**
* Returns the matching file info
*
* @return \OCP\Files\FileInfo
* @return FileInfo
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getFileInfo() {
if (!Filesystem::isValidPath($this->path)) {
throw new InvalidPathException();
}
if (!$this->fileInfo) {
$this->fileInfo = $this->view->getFileInfo($this->path);
$fileInfo = $this->view->getFileInfo($this->path);
if ($fileInfo instanceof FileInfo) {
$this->fileInfo = $fileInfo;
} else {
throw new NotFoundException();
}
}
return $this->fileInfo;
}
@@ -138,6 +152,8 @@ class Node implements \OCP\Files\Node {
/**
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getId() {
return $this->getFileInfo()->getId();
@@ -152,6 +168,8 @@ class Node implements \OCP\Files\Node {
/**
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getMTime() {
return $this->getFileInfo()->getMTime();
@@ -159,6 +177,8 @@ class Node implements \OCP\Files\Node {
/**
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getSize() {
return $this->getFileInfo()->getSize();
@@ -166,6 +186,8 @@ class Node implements \OCP\Files\Node {
/**
* @return string
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getEtag() {
return $this->getFileInfo()->getEtag();
@@ -173,6 +195,8 @@ class Node implements \OCP\Files\Node {
/**
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getPermissions() {
return $this->getFileInfo()->getPermissions();
@@ -180,6 +204,8 @@ class Node implements \OCP\Files\Node {
/**
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isReadable() {
return $this->getFileInfo()->isReadable();
@@ -187,6 +213,8 @@ class Node implements \OCP\Files\Node {
/**
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isUpdateable() {
return $this->getFileInfo()->isUpdateable();
@@ -194,6 +222,8 @@ class Node implements \OCP\Files\Node {
/**
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isDeletable() {
return $this->getFileInfo()->isDeletable();
@@ -201,11 +231,18 @@ class Node implements \OCP\Files\Node {
/**
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isShareable() {
return $this->getFileInfo()->isShareable();
}
/**
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isCreatable() {
return $this->getFileInfo()->isCreatable();
}

View File

@@ -451,8 +451,11 @@ class View {
}
/**
* @param string $path1
* @param string $path2
* Rename/move a file or folder from the source path to target path.
*
* @param string $path1 source path
* @param string $path2 target path
*
* @return bool|mixed
*/
public function rename($path1, $path2) {
@@ -494,7 +497,7 @@ class View {
$mount = $manager->find($absolutePath1 . $postFix1);
$storage1 = $mount->getStorage();
$internalPath1 = $mount->getInternalPath($absolutePath1 . $postFix1);
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
list($storage2, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
if ($internalPath1 === '' and $mount instanceof MoveableMount) {
if ($this->isTargetAllowed($absolutePath2)) {
/**
@@ -523,8 +526,10 @@ class View {
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
$this->touch($path2, $this->filemtime($path1));
list(, $result) = \OC_Helper::streamCopy($source, $target);
if ($result !== false) {
$this->touch($path2, $this->filemtime($path1));
}
// close open handle - especially $source is necessary because unlink below will
// throw an exception on windows because the file is locked
@@ -533,6 +538,11 @@ class View {
if ($result !== false) {
$result &= $storage1->unlink($internalPath1);
} else {
// delete partially written target file
$storage2->unlink($internalPath2);
// delete cache entry that was created by fopen
$storage2->getCache()->remove($internalPath2);
}
}
}
@@ -564,6 +574,15 @@ class View {
}
}
/**
* Copy a file/folder from the source path to target path
*
* @param string $path1 source path
* @param string $path2 target path
* @param bool $preserveMtime whether to preserve mtime on the copy
*
* @return bool|mixed
*/
public function copy($path1, $path2, $preserveMtime = false) {
$postFix1 = (substr($path1, -1, 1) === '/') ? '/' : '';
$postFix2 = (substr($path2, -1, 1) === '/') ? '/' : '';
@@ -603,6 +622,11 @@ class View {
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
if ($storage) {
$result = $storage->copy($internalPath1, $internalPath2);
if (!$result) {
// delete partially written target file
$storage->unlink($internalPath2);
$storage->getCache()->remove($internalPath2);
}
} else {
$result = false;
}
@@ -620,14 +644,20 @@ class View {
}
}
} else {
list($storage2, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
if($preserveMtime) {
list(, $result) = \OC_Helper::streamCopy($source, $target);
if($result && $preserveMtime) {
$this->touch($path2, $this->filemtime($path1));
}
fclose($source);
fclose($target);
if (!$result) {
// delete partially written target file
$storage2->unlink($internalPath2);
$storage2->getCache()->remove($internalPath2);
}
}
}
$this->updater->update($path2);

View File

@@ -578,13 +578,23 @@ class OC_Helper {
if (!$source or !$target) {
return array(0, false);
}
$bufSize = 8192;
$result = true;
$count = 0;
while (!feof($source)) {
if (($c = fwrite($target, fread($source, 8192))) === false) {
$buf = fread($source, $bufSize);
$bytesWritten = fwrite($target, $buf);
if ($bytesWritten !== false) {
$count += $bytesWritten;
}
// note: strlen is expensive so only use it when necessary,
// on the last block
if ($bytesWritten === false
|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
) {
// write error, could be disk full ?
$result = false;
} else {
$count += $c;
break;
}
}
return array($count, $result);

View File

@@ -391,7 +391,7 @@ class OC_Image {
$rotate = 90;
break;
}
if($flip) {
if($flip && function_exists('imageflip')) {
imageflip($this->resource, IMG_FLIP_HORIZONTAL);
}
if ($rotate) {

View File

@@ -241,7 +241,7 @@ class OC_Installer{
if(!isset($data['href'])) {
throw new \Exception($l->t("No href specified when installing app from http"));
}
copy($data['href'], $path);
file_put_contents($path, \OC_Util::getUrlContent($data['href']));
}else{
if(!isset($data['path'])) {
throw new \Exception($l->t("No path specified when installing app from local file"));

View File

@@ -14,6 +14,8 @@ class APCu extends APC {
return false;
} elseif (!ini_get('apc.enable_cli') && \OC::$CLI) {
return false;
} elseif (version_compare(phpversion('apc'), '4.0.6') === -1) {
return false;
} else {
return true;
}

View File

@@ -64,12 +64,11 @@ class SecureRandom implements ISecureRandom {
* Generate a random string of specified length.
* @param string $length The length of the generated string
* @param string $characters An optional list of characters to use if no characterlist is
* specified 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./
* is used.
* specified all valid base64 characters except + (plus sign) are used.
* @return string
* @throws \Exception If the generator is not initialized.
*/
public function generate($length, $characters = '') {
public function generate($length, $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./') {
if(is_null($this->generator)) {
throw new \Exception('Generator is not initialized.');
}

View File

@@ -1850,7 +1850,7 @@ class Share extends \OC\Share\Constants {
$sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
$sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
$shareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
$userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
if ($sourceExists) {
$fileTarget = $sourceExists['file_target'];
@@ -1863,12 +1863,12 @@ class Share extends \OC\Share\Constants {
} elseif(!$sourceExists && !$isGroupShare) {
$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $user,
$itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
$uidOwner, $suggestedItemTarget, $parent);
if (isset($fileSource)) {
if ($parentFolder) {
if ($parentFolder === true) {
$fileTarget = Helper::generateTarget('file', $filePath, $shareType, $user,
$fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user,
$uidOwner, $suggestedFileTarget, $parent);
if ($fileTarget != $groupFileTarget) {
$parentFolders[$user]['folder'] = $fileTarget;
@@ -1878,7 +1878,7 @@ class Share extends \OC\Share\Constants {
$parent = $parentFolder[$user]['id'];
}
} else {
$fileTarget = Helper::generateTarget('file', $filePath, $shareType,
$fileTarget = Helper::generateTarget('file', $filePath, $userShareType,
$user, $uidOwner, $suggestedFileTarget, $parent);
}
} else {
@@ -1909,7 +1909,7 @@ class Share extends \OC\Share\Constants {
'itemType' => $itemType,
'itemSource' => $itemSource,
'itemTarget' => $itemTarget,
'shareType' => $shareType,
'shareType' => $userShareType,
'shareWith' => $user,
'uidOwner' => $uidOwner,
'permissions' => $permissions,

View File

@@ -45,7 +45,8 @@ class OC_TemplateLayout extends OC_Template {
// Update notification
if($this->config->getSystemValue('updatechecker', true) === true &&
OC_User::isAdminUser(OC_User::getUser())) {
$updater = new \OC\Updater(\OC::$server->getHTTPHelper(), \OC::$server->getAppConfig());
$updater = new \OC\Updater(\OC::$server->getHTTPHelper(),
\OC::$server->getConfig());
$data = $updater->check();
if(isset($data['version']) && $data['version'] != '' and $data['version'] !== Array()) {

View File

@@ -132,12 +132,14 @@ class TempManager implements ITempManager {
$cutOfTime = time() - 3600;
$files = array();
$dh = opendir($this->tmpBaseDir);
while (($file = readdir($dh)) !== false) {
if (substr($file, 0, 7) === 'oc_tmp_') {
$path = $this->tmpBaseDir . '/' . $file;
$mtime = filemtime($path);
if ($mtime < $cutOfTime) {
$files[] = $path;
if ($dh) {
while (($file = readdir($dh)) !== false) {
if (substr($file, 0, 7) === 'oc_tmp_') {
$path = $this->tmpBaseDir . '/' . $file;
$mtime = filemtime($path);
if ($mtime < $cutOfTime) {
$files[] = $path;
}
}
}
}

View File

@@ -9,6 +9,9 @@
namespace OC;
use OC\Hooks\BasicEmitter;
use OC_App;
use OC_Util;
use OCP\IConfig;
/**
* Class that handles autoupdating of ownCloud
@@ -21,29 +24,27 @@ use OC\Hooks\BasicEmitter;
*/
class Updater extends BasicEmitter {
/**
* @var \OC\Log $log
*/
/** @var \OC\Log $log */
private $log;
/**
* @var \OC\HTTPHelper $helper;
*/
/** @var \OC\HTTPHelper $helper */
private $httpHelper;
/**
* @var \OCP\IAppConfig;
*/
/** @var IConfig */
private $config;
/** @var bool */
private $simulateStepEnabled;
/** @var bool */
private $updateStepEnabled;
/**
* @param HTTPHelper $httpHelper
* @param IConfig $config
* @param \OC\Log $log
*/
public function __construct($httpHelper, $config, $log = null) {
public function __construct(HTTPHelper $httpHelper, IConfig $config, $log = null) {
$this->httpHelper = $httpHelper;
$this->log = $log;
$this->config = $config;
@@ -81,23 +82,23 @@ class Updater extends BasicEmitter {
public function check($updaterUrl = null) {
// Look up the cache - it is invalidated all 30 minutes
if (($this->config->getValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode($this->config->getValue('core', 'lastupdateResult'), true);
if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true);
}
if (is_null($updaterUrl)) {
$updaterUrl = 'https://apps.owncloud.com/updater.php';
}
$this->config->setValue('core', 'lastupdatedat', time());
$this->config->setAppValue('core', 'lastupdatedat', time());
if ($this->config->getValue('core', 'installedat', '') == '') {
$this->config->setValue('core', 'installedat', microtime(true));
if ($this->config->getAppValue('core', 'installedat', '') == '') {
$this->config->setAppValue('core', 'installedat', microtime(true));
}
$version = \OC_Util::getVersion();
$version['installed'] = $this->config->getValue('core', 'installedat');
$version['updated'] = $this->config->getValue('core', 'lastupdatedat');
$version['installed'] = $this->config->getAppValue('core', 'installedat');
$version['updated'] = $this->config->getAppValue('core', 'lastupdatedat');
$version['updatechannel'] = \OC_Util::getChannel();
$version['edition'] = \OC_Util::getEditionString();
$version['build'] = \OC_Util::getBuild();
@@ -125,7 +126,7 @@ class Updater extends BasicEmitter {
}
// Cache the result
$this->config->setValue('core', 'lastupdateResult', json_encode($data));
$this->config->setAppValue('core', 'lastupdateResult', json_encode($data));
return $tmp;
}
@@ -136,9 +137,9 @@ class Updater extends BasicEmitter {
* @return bool true if the operation succeeded, false otherwise
*/
public function upgrade() {
\OC_Config::setValue('maintenance', true);
$this->config->setSystemValue('maintenance', true);
$installedVersion = \OC_Config::getValue('version', '0.0.0');
$installedVersion = $this->config->getSystemValue('version', '0.0.0');
$currentVersion = implode('.', \OC_Util::getVersion());
if ($this->log) {
$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core'));
@@ -151,7 +152,7 @@ class Updater extends BasicEmitter {
$this->emit('\OC\Updater', 'failure', array($exception->getMessage()));
}
\OC_Config::setValue('maintenance', false);
$this->config->setSystemValue('maintenance', false);
$this->emit('\OC\Updater', 'maintenanceEnd');
}
@@ -199,10 +200,10 @@ class Updater extends BasicEmitter {
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
// (in case it didn't exist before)
file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
// pre-upgrade repairs
$repair = new \OC\Repair(\OC\Repair::getBeforeUpgradeRepairSteps());
$repair = new Repair(Repair::getBeforeUpgradeRepairSteps());
$repair->run();
// simulate DB upgrade
@@ -217,22 +218,18 @@ class Updater extends BasicEmitter {
if ($this->updateStepEnabled) {
$this->doCoreUpgrade();
$disabledApps = \OC_App::checkAppsRequirements();
if (!empty($disabledApps)) {
$this->emit('\OC\Updater', 'disabledApps', array($disabledApps));
}
$this->checkAppsRequirements();
$this->doAppUpgrade();
// post-upgrade repairs
$repair = new \OC\Repair(\OC\Repair::getRepairSteps());
$repair = new Repair(Repair::getRepairSteps());
$repair->run();
//Invalidate update feed
$this->config->setValue('core', 'lastupdatedat', 0);
$this->config->setAppValue('core', 'lastupdatedat', 0);
// only set the final version if everything went well
\OC_Config::setValue('version', implode('.', \OC_Util::getVersion()));
$this->config->setSystemValue('version', implode('.', \OC_Util::getVersion()));
}
}
@@ -257,14 +254,11 @@ class Updater extends BasicEmitter {
$apps = \OC_App::getEnabledApps();
foreach ($apps as $appId) {
if ($version) {
$info = \OC_App::getAppInfo($appId);
$compatible = \OC_App::isAppCompatible($version, $info);
} else {
$compatible = true;
}
$info = \OC_App::getAppInfo($appId);
$compatible = \OC_App::isAppCompatible($version, $info);
$isShipped = \OC_App::isShipped($appId);
if ($compatible && \OC_App::shouldUpgrade($appId)) {
if ($compatible && $isShipped && \OC_App::shouldUpgrade($appId)) {
/**
* FIXME: The preupdate check is performed before the database migration, otherwise database changes
* are not possible anymore within it. - Consider this when touching the code.
@@ -291,15 +285,94 @@ class Updater extends BasicEmitter {
include \OC_App::getAppPath($appId) . '/appinfo/preupdate.php';
}
/**
* upgrades all apps within a major ownCloud upgrade. Also loads "priority"
* (types authentication, filesystem, logging, in that order) afterwards.
*
* @throws NeedsUpdateException
*/
protected function doAppUpgrade() {
$apps = \OC_App::getEnabledApps();
$priorityTypes = array('authentication', 'filesystem', 'logging');
$pseudoOtherType = 'other';
$stacks = array($pseudoOtherType => array());
foreach ($apps as $appId) {
if (\OC_App::shouldUpgrade($appId)) {
\OC_App::updateApp($appId);
$this->emit('\OC\Updater', 'appUpgrade', array($appId, \OC_App::getAppVersion($appId)));
$priorityType = false;
foreach ($priorityTypes as $type) {
if(!isset($stacks[$type])) {
$stacks[$type] = array();
}
if (\OC_App::isType($appId, $type)) {
$stacks[$type][] = $appId;
$priorityType = true;
break;
}
}
if (!$priorityType) {
$stacks[$pseudoOtherType][] = $appId;
}
}
foreach ($stacks as $type => $stack) {
foreach ($stack as $appId) {
if (\OC_App::shouldUpgrade($appId)) {
\OC_App::updateApp($appId);
$this->emit('\OC\Updater', 'appUpgrade', array($appId, \OC_App::getAppVersion($appId)));
}
if($type !== $pseudoOtherType) {
// load authentication, filesystem and logging apps after
// upgrading them. Other apps my need to rely on modifying
// user and/or filesystem aspects.
\OC_App::loadApp($appId, false);
}
}
}
}
/**
* check if the current enabled apps are compatible with the current
* ownCloud version. disable them if not.
* This is important if you upgrade ownCloud and have non ported 3rd
* party apps installed.
*/
private function checkAppsRequirements() {
$isCoreUpgrade = $this->isCodeUpgrade();
$apps = OC_App::getEnabledApps();
$version = OC_Util::getVersion();
foreach ($apps as $app) {
// check if the app is compatible with this version of ownCloud
$info = OC_App::getAppInfo($app);
if(!OC_App::isAppCompatible($version, $info)) {
OC_App::disable($app);
$this->emit('\OC\Updater', 'incompatibleAppDisabled', array($app));
}
// no need to disable any app in case this is a non-core upgrade
if (!$isCoreUpgrade) {
continue;
}
// shipped apps will remain enabled
if (OC_App::isShipped($app)) {
continue;
}
// authentication and session apps will remain enabled as well
if (OC_App::isType($app, ['session', 'authentication'])) {
continue;
}
// disable any other 3rd party apps
\OC_App::disable($app);
$this->emit('\OC\Updater', 'thirdPartyAppDisabled', array($app));
}
}
private function isCodeUpgrade() {
$installedVersion = $this->config->getSystemValue('version', '0.0.0');
$currentVersion = implode('.', OC_Util::getVersion());
if (version_compare($currentVersion, $installedVersion, '>')) {
return true;
}
return false;
}
}

View File

@@ -366,7 +366,7 @@ class OC_User {
return $backend->getLogoutAttribute();
}
return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . OC_Util::callRegister() . '"';
return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . urlencode(OC_Util::callRegister()) . '"';
}
/**

View File

@@ -504,11 +504,6 @@ class OC_Util {
$webServerRestart = true;
}
//common hint for all file permissions error messages
$permissionsHint = $l->t('Permissions can usually be fixed by '
. '%sgiving the webserver write access to the root directory%s.',
array('<a href="' . \OC_Helper::linkToDocs('admin-dir_permissions') . '" target="_blank">', '</a>'));
// Check if config folder is writable.
if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
$errors[] = array(
@@ -549,6 +544,10 @@ class OC_Util {
);
}
} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
//common hint for all file permissions error messages
$permissionsHint = $l->t('Permissions can usually be fixed by '
. '%sgiving the webserver write access to the root directory%s.',
array('<a href="' . \OC_Helper::linkToDocs('admin-dir_permissions') . '" target="_blank">', '</a>'));
$errors[] = array(
'error' => 'Data directory (' . $CONFIG_DATADIRECTORY . ') not writable by ownCloud',
'hint' => $permissionsHint
@@ -1400,10 +1399,12 @@ class OC_Util {
}
/**
* Check if PhpCharset config is UTF-8
*
* @return string
*/
public static function isPhpCharSetUtf8() {
return ini_get('default_charset') === 'UTF-8';
return strtoupper(ini_get('default_charset')) === 'UTF-8';
}
}

View File

@@ -89,6 +89,8 @@ interface Node extends FileInfo {
* Get the internal file id for the file or folder
*
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getId();
@@ -106,6 +108,8 @@ interface Node extends FileInfo {
* Get the modified date of the file or folder as unix timestamp
*
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getMTime();
@@ -113,6 +117,8 @@ interface Node extends FileInfo {
* Get the size of the file or folder in bytes
*
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getSize();
@@ -122,6 +128,8 @@ interface Node extends FileInfo {
* every time the file or folder is changed the Etag will change to
*
* @return string
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getEtag();
@@ -135,6 +143,8 @@ interface Node extends FileInfo {
* - \OCP\Constants::PERMISSION_SHARE
*
* @return int
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getPermissions();
@@ -142,6 +152,8 @@ interface Node extends FileInfo {
* Check if the file or folder is readable
*
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isReadable();
@@ -149,6 +161,8 @@ interface Node extends FileInfo {
* Check if the file or folder is writable
*
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isUpdateable();
@@ -156,6 +170,8 @@ interface Node extends FileInfo {
* Check if the file or folder is deletable
*
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isDeletable();
@@ -163,6 +179,8 @@ interface Node extends FileInfo {
* Check if the file or folder is shareable
*
* @return bool
* @throws InvalidPathException
* @throws NotFoundException
*/
public function isShareable();

View File

@@ -109,7 +109,6 @@ interface IConfig {
*/
public function deleteAppValues($appName);
/**
* Set a user defined value
*

View File

@@ -53,9 +53,10 @@ interface ISecureRandom {
/**
* Generate a random string of specified length.
* @param string $length The length of the generated string
* @param string $characters An optional list of characters to use
* @param string $characters An optional list of characters to use if no characterlist is
* specified all valid base64 characters except + (plus sign) are used.
* @return string
* @throws \Exception
* @throws \Exception If the generator is not initialized.
*/
public function generate($length, $characters = '');
}

View File

@@ -84,6 +84,10 @@ $template->assign('databaseOverload', $databaseOverload);
// warn if Windows is used
$template->assign('WindowsWarning', OC_Util::runningOnWindows());
// warn if outdated version of APCu is used
$template->assign('ApcuOutdatedWarning',
extension_loaded('apcu') && version_compare(phpversion('apc'), '4.0.6') === -1);
// add hardcoded forms from the template
$forms = OC_App::getForms('admin');
$l = OC_L10N::get('settings');

View File

@@ -11,8 +11,7 @@ $appId = $_POST['appid'];
$appId = OC_App::cleanAppId($appId);
// FIXME: Clear the cache - move that into some sane helper method
\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0');
\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1');
\OC::$server->getMemCacheFactory()->create('settings')->clear('listApps-');
OC_App::disable($appId);
OC_JSON::success();

View File

@@ -8,8 +8,7 @@ $groups = isset($_POST['groups']) ? $_POST['groups'] : null;
try {
OC_App::enable(OC_App::cleanAppId($_POST['appid']), $groups);
// FIXME: Clear the cache - move that into some sane helper method
\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0');
\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1');
\OC::$server->getMemCacheFactory()->create('settings')->clear('listApps-');
OC_JSON::success();
} catch (Exception $e) {
OC_Log::write('core', $e->getMessage(), OC_Log::ERROR);

View File

@@ -154,7 +154,7 @@ class UsersController extends Controller {
'subadmin' => \OC_SubAdmin::getSubAdminsGroups($user->getUID()),
'quota' => $this->config->getUserValue($user->getUID(), 'files', 'quota', 'default'),
'storageLocation' => $user->getHome(),
'lastLogin' => $user->getLastLogin(),
'lastLogin' => $user->getLastLogin() * 1000,
'backend' => $user->getBackendClassName(),
'email' => $this->config->getUserValue($user->getUID(), 'settings', 'email', ''),
'isRestoreDisabled' => !$restorePossible,

View File

@@ -1,7 +1,7 @@
OC.L10N.register(
"settings",
{
"Security & Setup Warnings" : "Güvelik ve Kurulum Uyarıları",
"Security & Setup Warnings" : "Güvenlik ve Kurulum Uyarıları",
"Cron" : "Cron",
"Sharing" : "Paylaşım",
"Security" : "Güvenlik",

View File

@@ -1,5 +1,5 @@
{ "translations": {
"Security & Setup Warnings" : "Güvelik ve Kurulum Uyarıları",
"Security & Setup Warnings" : "Güvenlik ve Kurulum Uyarıları",
"Cron" : "Cron",
"Sharing" : "Paylaşım",
"Security" : "Güvenlik",
@@ -264,4 +264,4 @@
"change email address" : "e-posta adresini değiştir",
"Default" : "Öntanımlı"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}
}

View File

@@ -143,9 +143,24 @@ if ($_['WindowsWarning']) {
</p>
</div>
<?php
}
// APCU Warning if outdated
if ($_['ApcuOutdatedWarning']) {
?>
<div class="section">
<h2><?php p($l->t('APCu below version 4.0.6 installed'));?></h2>
<p class="securitywarning">
<?php p($l->t('APCu below version 4.0.6 is installed, for stability and performance reasons we recommend to update to a newer APCu version.')); ?>
</p>
</div>
<?php
}
// if module fileinfo available?
if (!$_['has_fileinfo']) {
?>

View File

@@ -52,7 +52,7 @@ class DependencyAnalyzer extends \PHPUnit_Framework_TestCase {
}));
$this->platformMock->expects($this->any())
->method('getOcVersion')
->will( $this->returnValue('8.0.1'));
->will( $this->returnValue('8.0.2'));
$this->l10nMock = $this->getMockBuilder('\OCP\IL10N')
->disableOriginalConstructor()
@@ -183,8 +183,12 @@ class DependencyAnalyzer extends \PHPUnit_Framework_TestCase {
return array(
// no version -> no missing dependency
array(array(), null),
array(array(), array('@attributes' => array('min-version' => '8', 'max-version' => '8'))),
array(array(), array('@attributes' => array('min-version' => '8.0', 'max-version' => '8.0'))),
array(array(), array('@attributes' => array('min-version' => '8.0.2', 'max-version' => '8.0.2'))),
array(array('ownCloud 8.0.3 or higher is required.'), array('@attributes' => array('min-version' => '8.0.3'))),
array(array('ownCloud 9 or higher is required.'), array('@attributes' => array('min-version' => '9'))),
array(array('ownCloud with a version lower than 5.1.2 is required.'), array('@attributes' => array('max-version' => '5.1.2'))),
array(array('ownCloud with a version lower than 8.0.1 is required.'), array('@attributes' => array('max-version' => '8.0.1'))),
);
}
@@ -208,7 +212,17 @@ class DependencyAnalyzer extends \PHPUnit_Framework_TestCase {
array(array('@attributes' => array('min-version' => '100.0'), '@value' => 'curl'))),
// curl in version 100.0 does not exist
array(array('Library curl with a version lower than 1.0.0 is required - available version 2.3.4.'),
array(array('@attributes' => array('max-version' => '1.0.0'), '@value' => 'curl')))
array(array('@attributes' => array('max-version' => '1.0.0'), '@value' => 'curl'))),
array(array('Library curl with a version lower than 2.3.3 is required - available version 2.3.4.'),
array(array('@attributes' => array('max-version' => '2.3.3'), '@value' => 'curl'))),
array(array('Library curl with a version higher than 2.3.5 is required - available version 2.3.4.'),
array(array('@attributes' => array('min-version' => '2.3.5'), '@value' => 'curl'))),
array(array(),
array(array('@attributes' => array('min-version' => '2.3.4', 'max-version' => '2.3.4'), '@value' => 'curl'))),
array(array(),
array(array('@attributes' => array('min-version' => '2.3', 'max-version' => '2.3'), '@value' => 'curl'))),
array(array(),
array(array('@attributes' => array('min-version' => '2', 'max-version' => '2'), '@value' => 'curl'))),
);
}
@@ -244,6 +258,7 @@ class DependencyAnalyzer extends \PHPUnit_Framework_TestCase {
array(array(), '5.4', '5.5'),
array(array('PHP 5.4.4 or higher is required.'), '5.4.4', null),
array(array('PHP with a version lower than 5.4.2 is required.'), null, '5.4.2'),
array(array(), '5.4', '5.4'),
);
}
}

73
tests/lib/cache/fileglobalgc.php vendored Normal file
View File

@@ -0,0 +1,73 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 Robin Appelman icewind@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace Test\Cache;
use Test\TestCase;
class FileGlobalGC extends TestCase {
/**
* @var string
*/
private $cacheDir;
/**
* @var \OC\Cache\FileGlobalGC
*/
private $gc;
public function setUp() {
$this->cacheDir = \OC::$server->getTempManager()->getTemporaryFolder();
$this->gc = new \OC\Cache\FileGlobalGC();
}
private function addCacheFile($name, $expire) {
file_put_contents($this->cacheDir . $name, 'foo');
touch($this->cacheDir . $name, $expire);
}
public function testGetExpiredEmpty() {
$this->assertEquals([], $this->gc->getExpiredPaths($this->cacheDir, time()));
}
public function testGetExpiredNone() {
$time = time();
$this->addCacheFile('foo', $time + 10);
$this->assertEquals([], $this->gc->getExpiredPaths($this->cacheDir, $time));
}
public function testGetExpired() {
$time = time();
$this->addCacheFile('foo', $time + 10);
$this->addCacheFile('bar', $time);
$this->addCacheFile('bar2', $time - 10);
$this->addCacheFile('asd', $time - 100);
$this->assertEquals([$this->cacheDir . 'asd', $this->cacheDir . 'bar2'], $this->gc->getExpiredPaths($this->cacheDir, $time));
}
public function testGetExpiredDirectory() {
$time = time();
$this->addCacheFile('foo', $time - 10);
mkdir($this->cacheDir . 'asd');
$this->assertEquals([$this->cacheDir . 'foo'], $this->gc->getExpiredPaths($this->cacheDir, $time));
}
}

View File

@@ -340,4 +340,19 @@ class Node extends \Test\TestCase {
$node = new \OC\Files\Node\Node($root, $view, '/bar/foo');
$node->touch(100);
}
/**
* @expectedException \OCP\Files\InvalidPathException
*/
public function testInvalidPath() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$node = new \OC\Files\Node\Node($root, $view, '/../foo');
$node->getFileInfo();
}
}

View File

@@ -99,6 +99,28 @@ class Quota extends \Test\Files\Storage\Storage {
$this->assertEquals('foobarqwe', $instance->file_get_contents('foo'));
}
public function testStreamCopyWithEnoughSpace() {
$instance = $this->getLimitedStorage(16);
$inputStream = fopen('data://text/plain,foobarqwerty', 'r');
$outputStream = $instance->fopen('foo', 'w+');
list($count, $result) = \OC_Helper::streamCopy($inputStream, $outputStream);
$this->assertEquals(12, $count);
$this->assertTrue($result);
fclose($inputStream);
fclose($outputStream);
}
public function testStreamCopyNotEnoughSpace() {
$instance = $this->getLimitedStorage(9);
$inputStream = fopen('data://text/plain,foobarqwerty', 'r');
$outputStream = $instance->fopen('foo', 'w+');
list($count, $result) = \OC_Helper::streamCopy($inputStream, $outputStream);
$this->assertEquals(9, $count);
$this->assertFalse($result);
fclose($inputStream);
fclose($outputStream);
}
public function testReturnFalseWhenFopenFailed() {
$failStorage = $this->getMock(
'\OC\Files\Storage\Local',

View File

@@ -872,6 +872,57 @@ class View extends \Test\TestCase {
$this->assertEquals($time, $view->filemtime('/test/sub/storage/foo/bar.txt'));
}
public function testRenameFailDeleteTargetKeepSource() {
$this->doTestCopyRenameFail('rename');
}
public function testCopyFailDeleteTargetKeepSource() {
$this->doTestCopyRenameFail('copy');
}
private function doTestCopyRenameFail($operation) {
$storage1 = new Temporary(array());
$storage2 = new Temporary(array());
$storage2 = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage2, 'quota' => 9));
$storage1->mkdir('sub');
$storage1->file_put_contents('foo.txt', '0123456789ABCDEFGH');
$storage1->mkdir('dirtomove');
$storage1->file_put_contents('dirtomove/indir1.txt', '0123456'); // fits
$storage1->file_put_contents('dirtomove/indir2.txt', '0123456789ABCDEFGH'); // doesn't fit
$storage2->file_put_contents('existing.txt', '0123');
$storage1->getScanner()->scan('');
$storage2->getScanner()->scan('');
\OC\Files\Filesystem::mount($storage1, array(), '/test/');
\OC\Files\Filesystem::mount($storage2, array(), '/test/sub/storage');
// move file
$view = new \OC\Files\View('');
$this->assertTrue($storage1->file_exists('foo.txt'));
$this->assertFalse($storage2->file_exists('foo.txt'));
$this->assertFalse($view->$operation('/test/foo.txt', '/test/sub/storage/foo.txt'));
$this->assertFalse($storage2->file_exists('foo.txt'));
$this->assertFalse($storage2->getCache()->get('foo.txt'));
$this->assertTrue($storage1->file_exists('foo.txt'));
// if target exists, it will be deleted too
$this->assertFalse($view->$operation('/test/foo.txt', '/test/sub/storage/existing.txt'));
$this->assertFalse($storage2->file_exists('existing.txt'));
$this->assertFalse($storage2->getCache()->get('existing.txt'));
$this->assertTrue($storage1->file_exists('foo.txt'));
// move folder
$this->assertFalse($view->$operation('/test/dirtomove/', '/test/sub/storage/dirtomove/'));
// since the move failed, the full source tree is kept
$this->assertTrue($storage1->file_exists('dirtomove/indir1.txt'));
// but the target file stays
$this->assertTrue($storage2->file_exists('dirtomove/indir1.txt'));
// second file not moved/copied
$this->assertTrue($storage1->file_exists('dirtomove/indir2.txt'));
$this->assertFalse($storage2->file_exists('dirtomove/indir2.txt'));
$this->assertFalse($storage2->getCache()->get('dirtomove/indir2.txt'));
}
public function testDeleteFailKeepCache() {
/**
* @var \PHPUnit_Framework_MockObject_MockObject | \OC\Files\Storage\Temporary $storage
@@ -894,4 +945,17 @@ class View extends \Test\TestCase {
$this->assertFalse($view->unlink('foo.txt'));
$this->assertTrue($cache->inCache('foo.txt'));
}
public function testRenameOverWrite() {
$storage = new Temporary(array());
$scanner = $storage->getScanner();
$storage->mkdir('sub');
$storage->mkdir('foo');
$storage->file_put_contents('foo.txt', 'asd');
$storage->file_put_contents('foo/bar.txt', 'asd');
$scanner->scan('');
\OC\Files\Filesystem::mount($storage, array(), '/test/');
$view = new \OC\Files\View('');
$this->assertTrue($view->rename('/test/foo.txt', '/test/foo/bar.txt'));
}
}

View File

@@ -586,7 +586,10 @@ class Test_Share extends \Test\TestCase {
// Attempt user specific target conflict
OC_User::setUserId($this->user3);
\OCP\Util::connectHook('OCP\\Share', 'post_shared', 'DummyHookListener', 'listen');
$this->assertTrue(OCP\Share::shareItem('test', 'share.txt', OCP\Share::SHARE_TYPE_GROUP, $this->group1, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE));
$this->assertEquals(OCP\Share::SHARE_TYPE_GROUP, DummyHookListener::$shareType);
OC_User::setUserId($this->user2);
$to_test = OCP\Share::getItemsSharedWith('test', Test_Share_Backend::FORMAT_TARGET);
$this->assertEquals(2, count($to_test));
@@ -1055,3 +1058,11 @@ class DummyShareClass extends \OC\Share\Share {
return parent::groupItems($items, 'test');
}
}
class DummyHookListener {
static $shareType = null;
public static function listen($params) {
self::$shareType = $params['shareType'];
}
}

View File

@@ -88,7 +88,7 @@ class UpdaterTest extends \Test\TestCase {
protected function getUpdaterMock($content){
// Invalidate cache
$mockedAppConfig = $this->getMockBuilder('\OC\AppConfig')
$mockedConfig = $this->getMockBuilder('\OCP\IConfig')
->disableOriginalConstructor()
->getMock()
;
@@ -101,7 +101,7 @@ class UpdaterTest extends \Test\TestCase {
$mockedHTTPHelper->expects($this->once())->method('getUrlContent')->will($this->returnValue($content));
return new Updater($mockedHTTPHelper, $mockedAppConfig);
return new Updater($mockedHTTPHelper, $mockedConfig);
}
}

View File

@@ -162,7 +162,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 1024,
'storageLocation' => '/home/foo',
'lastLogin' => 500,
'lastLogin' => 500000,
'backend' => 'OC_User_Database',
'email' => 'foo@bar.com',
'isRestoreDisabled' => false,
@@ -174,7 +174,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 404,
'storageLocation' => '/home/admin',
'lastLogin' => 12,
'lastLogin' => 12000,
'backend' => 'OC_User_Dummy',
'email' => 'admin@bar.com',
'isRestoreDisabled' => false,
@@ -186,7 +186,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 2323,
'storageLocation' => '/home/bar',
'lastLogin' => 3999,
'lastLogin' => 3999000,
'backend' => 'OC_User_Dummy',
'email' => 'bar@dummy.com',
'isRestoreDisabled' => false,
@@ -330,7 +330,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => [],
'quota' => 1024,
'storageLocation' => '/home/foo',
'lastLogin' => 500,
'lastLogin' => 500000,
'backend' => 'OC_User_Database',
'email' => 'foo@bar.com',
'isRestoreDisabled' => false,
@@ -342,7 +342,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => [],
'quota' => 404,
'storageLocation' => '/home/admin',
'lastLogin' => 12,
'lastLogin' => 12000,
'backend' => 'OC_User_Dummy',
'email' => 'admin@bar.com',
'isRestoreDisabled' => false,
@@ -354,7 +354,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => [],
'quota' => 2323,
'storageLocation' => '/home/bar',
'lastLogin' => 3999,
'lastLogin' => 3999000,
'backend' => 'OC_User_Dummy',
'email' => 'bar@dummy.com',
'isRestoreDisabled' => false,
@@ -461,7 +461,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 1024,
'storageLocation' => '/home/foo',
'lastLogin' => 500,
'lastLogin' => 500000,
'backend' => 'OC_User_Database',
'email' => 'foo@bar.com',
'isRestoreDisabled' => false,
@@ -473,7 +473,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 404,
'storageLocation' => '/home/admin',
'lastLogin' => 12,
'lastLogin' => 12000,
'backend' => 'OC_User_Dummy',
'email' => 'admin@bar.com',
'isRestoreDisabled' => false,
@@ -485,7 +485,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => 2323,
'storageLocation' => '/home/bar',
'lastLogin' => 3999,
'lastLogin' => 3999000,
'backend' => 'OC_User_Dummy',
'email' => 'bar@dummy.com',
'isRestoreDisabled' => false,
@@ -545,7 +545,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => null,
'storageLocation' => '/home/foo',
'lastLogin' => 500,
'lastLogin' => 500000,
'backend' => 'OC_User_Database',
'email' => null,
'isRestoreDisabled' => false,
@@ -1239,7 +1239,7 @@ class UsersControllerTest extends \Test\TestCase {
'subadmin' => array(),
'quota' => null,
'storageLocation' => $home,
'lastLogin' => $lastLogin,
'lastLogin' => $lastLogin * 1000,
'backend' => $backend,
'email' => null,
'isRestoreDisabled' => false,

View File

@@ -3,10 +3,10 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version=array(8, 0, 0, 7);
$OC_Version=array(8, 0, 2, 0);
// The human readable string
$OC_VersionString='8.0';
$OC_VersionString='8.0.2';
// The ownCloud channel
$OC_Channel='git';