aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.drone.yml24
-rw-r--r--.travis.yml14
m---------3rdparty0
-rw-r--r--apps/dav/lib/CardDAV/AddressBookImpl.php42
-rw-r--r--apps/dav/tests/unit/CardDAV/AddressBookImplTest.php65
-rw-r--r--apps/federatedfilesharing/tests/AddressHandlerTest.php6
-rw-r--r--apps/federatedfilesharing/tests/DiscoveryManagerTest.php18
-rw-r--r--apps/federatedfilesharing/tests/FederatedShareProviderTest.php32
-rw-r--r--apps/federatedfilesharing/tests/NotificationsTest.php4
-rw-r--r--apps/federatedfilesharing/tests/TokenHandlerTest.php2
-rw-r--r--apps/files_external/templates/list.php2
-rw-r--r--apps/files_sharing/lib/Controller/ShareesAPIController.php2
-rw-r--r--apps/files_sharing/lib/SharedMount.php8
-rw-r--r--apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php52
-rw-r--r--apps/files_trashbin/appinfo/register_command.php6
-rw-r--r--apps/files_trashbin/lib/Command/ExpireTrash.php127
-rw-r--r--apps/files_versions/appinfo/register_command.php5
-rw-r--r--apps/files_versions/lib/Command/ExpireVersions.php125
-rw-r--r--build/integration/features/bootstrap/BasicStructure.php24
-rw-r--r--build/integration/features/external-storage.feature26
-rw-r--r--build/integration/features/provisioning-v1.feature13
-rwxr-xr-xbuild/integration/run.sh15
-rw-r--r--core/ajax/preview.php2
-rw-r--r--core/js/mimetypelist.js3
-rw-r--r--index.php8
-rw-r--r--lib/base.php3
-rw-r--r--lib/private/AppFramework/Http/Request.php17
-rw-r--r--lib/private/Encryption/DecryptAll.php4
-rw-r--r--lib/private/Files/Config/UserMountCache.php3
-rw-r--r--lib/private/Preview.php2
-rw-r--r--lib/private/Security/Bruteforce/Throttler.php5
-rw-r--r--lib/private/User/Session.php3
-rw-r--r--resources/config/mimetypealiases.dist.json3
-rw-r--r--tests/lib/AppFramework/Http/RequestTest.php78
-rw-r--r--tests/lib/Encryption/DecryptAllTest.php17
-rw-r--r--tests/lib/User/SessionTest.php12
36 files changed, 680 insertions, 92 deletions
diff --git a/.drone.yml b/.drone.yml
index 2798176c9a2..6016ebd6981 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -3,18 +3,6 @@ build:
image: nextcloudci/jsunit:1.0.6
commands:
- ./autotest-js.sh
- nodb-php5.4:
- image: nextcloudci/php5.4:1.0.7
- commands:
- - rm -rf data/* config/config.php # TODO: remove this - temporary fix for CI issues
- - git submodule update --init
- - NOCOVERAGE=true TEST_SELECTION=NODB ./autotest.sh sqlite
- nodb-php5.5:
- image: nextcloudci/php5.5:1.0.7
- commands:
- - rm -rf data/* config/config.php # TODO: remove this - temporary fix for CI issues
- - git submodule update --init
- - NOCOVERAGE=true TEST_SELECTION=NODB ./autotest.sh sqlite
nodb-php5.6:
image: nextcloudci/php5.6:1.0.6
commands:
@@ -27,18 +15,6 @@ build:
- rm -rf data/* config/config.php # TODO: remove this - temporary fix for CI issues
- git submodule update --init
- NOCOVERAGE=true TEST_SELECTION=NODB ./autotest.sh sqlite
- sqlite-php5.4:
- image: nextcloudci/php5.4:1.0.7
- commands:
- - rm -rf data/* config/config.php # TODO: remove this - temporary fix for CI issues
- - git submodule update --init
- - NOCOVERAGE=true TEST_SELECTION=DB ./autotest.sh sqlite
- sqlite-php5.5:
- image: nextcloudci/php5.5:1.0.7
- commands:
- - rm -rf data/* config/config.php # TODO: remove this - temporary fix for CI issues
- - git submodule update --init
- - NOCOVERAGE=true TEST_SELECTION=DB ./autotest.sh sqlite
sqlite-php5.6:
image: nextcloudci/php5.6:1.0.6
commands:
diff --git a/.travis.yml b/.travis.yml
index 05b07beac3d..ddcba167af1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
sudo: false
language: php
php:
- - 5.4
+ - 5.6
env:
global:
@@ -41,21 +41,17 @@ matrix:
include:
- php: 7.0
env: TC=autoloader;TEST_DAV=0
- - php: 5.4
+ - php: 5.6
env: DB=pgsql;TC=litmus-v1
- - php: 5.4
+ - php: 5.6
env: DB=sqlite;TC=carddav
- - php: 5.4
+ - php: 5.6
env: DB=sqlite;TC=caldav
- - php: 5.4
- env: DB=sqlite;TC=syntax;TEST_DAV=0
- - php: 5.5
- env: DB=sqlite;TC=syntax;TEST_DAV=0
- php: 5.6
env: DB=sqlite;TC=syntax;TEST_DAV=0
- php: 7.0
env: DB=sqlite;TC=syntax;TEST_DAV=0
- - php: 5.4
+ - php: 5.6
env: DB=sqlite;TC=app:check-code;TEST_DAV=0
fast_finish: true
diff --git a/3rdparty b/3rdparty
-Subproject cba0f29cd541dc796dbc41d79fca9171321cb2e
+Subproject 1b3ecc4859174daf3ea39400d689db87e0672e3
diff --git a/apps/dav/lib/CardDAV/AddressBookImpl.php b/apps/dav/lib/CardDAV/AddressBookImpl.php
index c83ee613d37..9de54eec33d 100644
--- a/apps/dav/lib/CardDAV/AddressBookImpl.php
+++ b/apps/dav/lib/CardDAV/AddressBookImpl.php
@@ -28,6 +28,7 @@ use OCP\Constants;
use OCP\IAddressBook;
use OCP\IURLGenerator;
use Sabre\VObject\Component\VCard;
+use Sabre\VObject\Property;
use Sabre\VObject\Property\Text;
use Sabre\VObject\Reader;
use Sabre\VObject\UUIDUtil;
@@ -225,7 +226,7 @@ class AddressBookImpl implements IAddressBook {
];
foreach ($vCard->children as $property) {
- $result[$property->name] = $property->getValue();
+ /** @var \Sabre\VObject\Property\Unknown $property */
if ($property->name === 'PHOTO' && $property->getValueType() === 'BINARY') {
$url = $this->urlGenerator->getAbsoluteURL(
$this->urlGenerator->linkTo('', 'remote.php') . '/dav/');
@@ -237,14 +238,53 @@ class AddressBookImpl implements IAddressBook {
]) . '?photo';
$result['PHOTO'] = 'VALUE=uri:' . $url;
+
+ } else if ($property->name === 'X-SOCIALPROFILE') {
+ $type = $this->getTypeFromProperty($property);
+
+ // Type is the social network, when it's empty we don't need this.
+ if ($type !== null) {
+ if (!isset($result[$property->name])) {
+ $result[$property->name] = [];
+ }
+ $result[$property->name][$type] = $property->getValue();
+ }
+
+ // The following properties can be set multiple times
+ } else if (in_array($property->name, ['CLOUD', 'EMAIL', 'IMPP', 'TEL', 'URL'])) {
+ if (!isset($result[$property->name])) {
+ $result[$property->name] = [];
+ }
+
+ $result[$property->name][] = $property->getValue();
+
} else {
$result[$property->name] = $property->getValue();
}
}
+
if ($this->addressBookInfo['principaluri'] === 'principals/system/system' &&
$this->addressBookInfo['uri'] === 'system') {
$result['isLocalSystemBook'] = true;
}
return $result;
}
+
+ /**
+ * Get the type of the current property
+ *
+ * @param Property $property
+ * @return null|string
+ */
+ protected function getTypeFromProperty(Property $property) {
+ $parameters = $property->parameters();
+ // Type is the social network, when it's empty we don't need this.
+ if (isset($parameters['TYPE'])) {
+ /** @var \Sabre\VObject\Parameter $type */
+ $type = $parameters['TYPE'];
+ return $type->getValue();
+ }
+
+ return null;
+ }
}
diff --git a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php
index ba8527dc76e..fa3cae27dec 100644
--- a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php
+++ b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php
@@ -60,7 +60,9 @@ class AddressBookImplTest extends TestCase {
$this->addressBookInfo = [
'id' => 42,
- '{DAV:}displayname' => 'display name'
+ 'uri' => 'system',
+ 'principaluri' => 'principals/system/system',
+ '{DAV:}displayname' => 'display name',
];
$this->addressBook = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBook')
->disableOriginalConstructor()->getMock();
@@ -306,4 +308,65 @@ class AddressBookImplTest extends TestCase {
$this->assertSame($expectedVCardSerialized, $resultSerialized);
}
+ public function testVCard2Array() {
+ $vCard = new VCard();
+
+ $vCard->add($vCard->createProperty('FN', 'Full Name'));
+
+ // Multi-value properties
+ $vCard->add($vCard->createProperty('CLOUD', 'cloud-user1@localhost'));
+ $vCard->add($vCard->createProperty('CLOUD', 'cloud-user2@example.tld'));
+ $vCard->add($vCard->createProperty('EMAIL', 'email-user1@localhost'));
+ $vCard->add($vCard->createProperty('EMAIL', 'email-user2@example.tld'));
+ $vCard->add($vCard->createProperty('IMPP', 'impp-user1@localhost'));
+ $vCard->add($vCard->createProperty('IMPP', 'impp-user2@example.tld'));
+ $vCard->add($vCard->createProperty('TEL', '+49 123456789'));
+ $vCard->add($vCard->createProperty('TEL', '+1 555 123456789'));
+ $vCard->add($vCard->createProperty('URL', 'https://localhost'));
+ $vCard->add($vCard->createProperty('URL', 'https://example.tld'));
+
+ // Type depending properties
+ $property = $vCard->createProperty('X-SOCIALPROFILE', 'tw-example');
+ $property->add('TYPE', 'twitter');
+ $vCard->add($property);
+ $property = $vCard->createProperty('X-SOCIALPROFILE', 'fb-example');
+ $property->add('TYPE', 'facebook');
+ $vCard->add($property);
+
+ $array = $this->invokePrivate($this->addressBookImpl, 'vCard2Array', ['uri', $vCard]);
+ unset($array['PRODID']);
+
+ $this->assertEquals([
+ 'URI' => 'uri',
+ 'VERSION' => '3.0',
+ 'FN' => 'Full Name',
+ 'CLOUD' => [
+ 'cloud-user1@localhost',
+ 'cloud-user2@example.tld',
+ ],
+ 'EMAIL' => [
+ 'email-user1@localhost',
+ 'email-user2@example.tld',
+ ],
+ 'IMPP' => [
+ 'impp-user1@localhost',
+ 'impp-user2@example.tld',
+ ],
+ 'TEL' => [
+ '+49 123456789',
+ '+1 555 123456789',
+ ],
+ 'URL' => [
+ 'https://localhost',
+ 'https://example.tld',
+ ],
+
+ 'X-SOCIALPROFILE' => [
+ 'twitter'=> 'tw-example',
+ 'facebook'=> 'fb-example',
+ ],
+
+ 'isLocalSystemBook' => true,
+ ], $array);
+ }
}
diff --git a/apps/federatedfilesharing/tests/AddressHandlerTest.php b/apps/federatedfilesharing/tests/AddressHandlerTest.php
index 9ae37bb251d..c2e69fb2bd7 100644
--- a/apps/federatedfilesharing/tests/AddressHandlerTest.php
+++ b/apps/federatedfilesharing/tests/AddressHandlerTest.php
@@ -43,8 +43,10 @@ class AddressHandlerTest extends \Test\TestCase {
public function setUp() {
parent::setUp();
- $this->urlGenerator = $this->getMock('OCP\IURLGenerator');
- $this->il10n = $this->getMock('OCP\IL10N');
+ $this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')
+ ->getMock();
+ $this->il10n = $this->getMockBuilder('OCP\IL10N')
+ ->getMock();
$this->addressHandler = new AddressHandler($this->urlGenerator, $this->il10n);
}
diff --git a/apps/federatedfilesharing/tests/DiscoveryManagerTest.php b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php
index ec79a16a3aa..77e24aad54b 100644
--- a/apps/federatedfilesharing/tests/DiscoveryManagerTest.php
+++ b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php
@@ -40,7 +40,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
public function setUp() {
parent::setUp();
- $this->cache = $this->getMock('\OCP\ICache');
+ $this->cache = $this->getMockBuilder('\OCP\ICache')
+ ->getMock();
/** @var ICacheFactory $cacheFactory */
$cacheFactory = $this->getMockBuilder('\OCP\ICacheFactory')
->disableOriginalConstructor()->getMock();
@@ -67,7 +68,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
}
public function testWithMalformedFormattedEndpointCached() {
- $response = $this->getMock('\OCP\Http\Client\IResponse');
+ $response = $this->getMockBuilder('\OCP\Http\Client\IResponse')
+ ->getMock();
$response
->expects($this->once())
->method('getStatusCode')
@@ -104,7 +106,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
}
public function testGetWebDavEndpointWithValidFormattedEndpointAndNotCached() {
- $response = $this->getMock('\OCP\Http\Client\IResponse');
+ $response = $this->getMockBuilder('\OCP\Http\Client\IResponse')
+ ->getMock();
$response
->expects($this->once())
->method('getStatusCode')
@@ -127,7 +130,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
}
public function testGetWebDavEndpointWithValidFormattedEndpointWithoutDataAndNotCached() {
- $response = $this->getMock('\OCP\Http\Client\IResponse');
+ $response = $this->getMockBuilder('\OCP\Http\Client\IResponse')
+ ->getMock();
$response
->expects($this->once())
->method('getStatusCode')
@@ -150,7 +154,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
}
public function testGetShareEndpointWithValidFormattedEndpointAndNotCached() {
- $response = $this->getMock('\OCP\Http\Client\IResponse');
+ $response = $this->getMockBuilder('\OCP\Http\Client\IResponse')
+ ->getMock();
$response
->expects($this->once())
->method('getStatusCode')
@@ -173,7 +178,8 @@ class DiscoveryManagerTest extends \Test\TestCase {
}
public function testWithMaliciousEndpointCached() {
- $response = $this->getMock('\OCP\Http\Client\IResponse');
+ $response = $this->getMockBuilder('\OCP\Http\Client\IResponse')
+ ->getMock();
$response
->expects($this->once())
->method('getStatusCode')
diff --git a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php
index d1a15158afa..e4c234fd038 100644
--- a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php
+++ b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php
@@ -80,15 +80,15 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->tokenHandler = $this->getMockBuilder('OCA\FederatedFileSharing\TokenHandler')
->disableOriginalConstructor()
->getMock();
- $this->l = $this->getMock('OCP\IL10N');
+ $this->l = $this->getMockBuilder('OCP\IL10N')->getMock();
$this->l->method('t')
->will($this->returnCallback(function($text, $parameters = []) {
return vsprintf($text, $parameters);
}));
- $this->logger = $this->getMock('OCP\ILogger');
- $this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
- $this->config = $this->getMock('OCP\IConfig');
- $this->userManager = $this->getMock('OCP\IUserManager');
+ $this->logger = $this->getMockBuilder('OCP\ILogger')->getMock();
+ $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock();
+ $this->config = $this->getMockBuilder('OCP\IConfig')->getMock();
+ $this->userManager = $this->getMockBuilder('OCP\IUserManager')->getMock();
//$this->addressHandler = new AddressHandler(\OC::$server->getURLGenerator(), $this->l);
$this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')->disableOriginalConstructor()->getMock();
@@ -118,7 +118,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
public function testCreate() {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -189,7 +189,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
public function testCreateCouldNotFindServer() {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -245,7 +245,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
public function testCreateException() {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -301,7 +301,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
public function testCreateShareWithSelf() {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -340,7 +340,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
public function testCreateAlreadyShared() {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -406,7 +406,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
$share = $this->shareManager->newShare();
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -463,7 +463,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
}
public function testGetSharedBy() {
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -504,7 +504,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
}
public function testGetSharedByWithNode() {
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -523,7 +523,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setNode($node);
$this->provider->create($share);
- $node2 = $this->getMock('\OCP\Files\File');
+ $node2 = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node2->method('getId')->willReturn(43);
$node2->method('getName')->willReturn('myOtherFile');
@@ -542,7 +542,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
}
public function testGetSharedByWithReshares() {
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
@@ -575,7 +575,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
}
public function testGetSharedByWithLimit() {
- $node = $this->getMock('\OCP\Files\File');
+ $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
diff --git a/apps/federatedfilesharing/tests/NotificationsTest.php b/apps/federatedfilesharing/tests/NotificationsTest.php
index 415afbd750c..dbcb1ef4e87 100644
--- a/apps/federatedfilesharing/tests/NotificationsTest.php
+++ b/apps/federatedfilesharing/tests/NotificationsTest.php
@@ -47,10 +47,10 @@ class NotificationsTest extends \Test\TestCase {
public function setUp() {
parent::setUp();
- $this->jobList = $this->getMock('OCP\BackgroundJob\IJobList');
+ $this->jobList = $this->getMockBuilder('OCP\BackgroundJob\IJobList')->getMock();
$this->discoveryManager = $this->getMockBuilder('OCA\FederatedFileSharing\DiscoveryManager')
->disableOriginalConstructor()->getMock();
- $this->httpClientService = $this->getMock('OCP\Http\Client\IClientService');
+ $this->httpClientService = $this->getMockBuilder('OCP\Http\Client\IClientService')->getMock();
$this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')
->disableOriginalConstructor()->getMock();
diff --git a/apps/federatedfilesharing/tests/TokenHandlerTest.php b/apps/federatedfilesharing/tests/TokenHandlerTest.php
index e6fc470b553..10e5fc5df51 100644
--- a/apps/federatedfilesharing/tests/TokenHandlerTest.php
+++ b/apps/federatedfilesharing/tests/TokenHandlerTest.php
@@ -42,7 +42,7 @@ class TokenHandlerTest extends \Test\TestCase {
public function setUp() {
parent::setUp();
- $this->secureRandom = $this->getMock('OCP\Security\ISecureRandom');
+ $this->secureRandom = $this->getMockBuilder('OCP\Security\ISecureRandom')->getMock();
$this->tokenHandler = new TokenHandler($this->secureRandom);
}
diff --git a/apps/files_external/templates/list.php b/apps/files_external/templates/list.php
index c2f68b9c5ba..d006514bcde 100644
--- a/apps/files_external/templates/list.php
+++ b/apps/files_external/templates/list.php
@@ -7,7 +7,7 @@
<div id="emptycontent" class="hidden">
<div class="icon-external"></div>
<h2><?php p($l->t('No external storage configured')); ?></h2>
- <p><?php p($l->t('You can add external storages in the personal settings')); ?></p>
+ <p><a href="<?php p(link_to('', 'index.php/settings/personal#files_external' )); ?>"><?php p($l->t('You can add external storages in the personal settings')); ?></a></p>
</div>
<input type="hidden" name="dir" value="" id="dir">
diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php
index b884aa9f1d4..a2063803450 100644
--- a/apps/files_sharing/lib/Controller/ShareesAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php
@@ -321,7 +321,7 @@ class ShareesAPIController extends OCSController {
$this->result['remotes'] = [];
}
- if (!$foundRemoteById && substr_count($search, '@') >= 1 && substr_count($search, ' ') === 0 && $this->offset === 0) {
+ if (!$foundRemoteById && substr_count($search, '@') >= 1 && $this->offset === 0) {
$this->result['exact']['remotes'][] = [
'label' => $search,
'value' => [
diff --git a/apps/files_sharing/lib/SharedMount.php b/apps/files_sharing/lib/SharedMount.php
index 2b562c4b4f1..13ecd88bfa9 100644
--- a/apps/files_sharing/lib/SharedMount.php
+++ b/apps/files_sharing/lib/SharedMount.php
@@ -246,6 +246,12 @@ class SharedMount extends MountPoint implements MoveableMount {
->from('filecache')
->where($builder->expr()->eq('fileid', $builder->createNamedParameter($this->getStorageRootId())));
- return $query->execute()->fetchColumn();
+ $result = $query->execute();
+ $row = $result->fetch();
+ $result->closeCursor();
+ if ($row) {
+ return $row['storage'];
+ }
+ return -1;
}
}
diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php
index 5cb073ecf08..161cc8a184b 100644
--- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php
+++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php
@@ -945,6 +945,58 @@ class ShareesAPIControllerTest extends TestCase {
[],
true,
],
+ // contact with space
+ [
+ 'user name@localhost',
+ [
+ [
+ 'FN' => 'User3 @ Localhost',
+ ],
+ [
+ 'FN' => 'User2 @ Localhost',
+ 'CLOUD' => [
+ ],
+ ],
+ [
+ 'FN' => 'User Name @ Localhost',
+ 'CLOUD' => [
+ 'user name@localhost',
+ ],
+ ],
+ ],
+ false,
+ [
+ ['label' => 'User Name @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']],
+ ],
+ [],
+ true,
+ ],
+ // remote with space, no contact
+ [
+ 'user space@remote',
+ [
+ [
+ 'FN' => 'User3 @ Localhost',
+ ],
+ [
+ 'FN' => 'User2 @ Localhost',
+ 'CLOUD' => [
+ ],
+ ],
+ [
+ 'FN' => 'User @ Localhost',
+ 'CLOUD' => [
+ 'username@localhost',
+ ],
+ ],
+ ],
+ false,
+ [
+ ['label' => 'user space@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user space@remote']],
+ ],
+ [],
+ true,
+ ],
];
}
diff --git a/apps/files_trashbin/appinfo/register_command.php b/apps/files_trashbin/appinfo/register_command.php
index 676e3f5891c..e0dafc60cd9 100644
--- a/apps/files_trashbin/appinfo/register_command.php
+++ b/apps/files_trashbin/appinfo/register_command.php
@@ -21,10 +21,16 @@
*/
+use OCA\Files_Trashbin\AppInfo\Application;
use OCA\Files_Trashbin\Command\CleanUp;
+use OCA\Files_Trashbin\Command\ExpireTrash;
+$app = new Application();
+$expiration = $app->getContainer()->query('Expiration');
$userManager = OC::$server->getUserManager();
$rootFolder = \OC::$server->getRootFolder();
$dbConnection = \OC::$server->getDatabaseConnection();
+
/** @var Symfony\Component\Console\Application $application */
$application->add(new CleanUp($rootFolder, $userManager, $dbConnection));
+$application->add(new ExpireTrash($userManager, $expiration));
diff --git a/apps/files_trashbin/lib/Command/ExpireTrash.php b/apps/files_trashbin/lib/Command/ExpireTrash.php
new file mode 100644
index 00000000000..ff827718885
--- /dev/null
+++ b/apps/files_trashbin/lib/Command/ExpireTrash.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud GmbH.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Trashbin\Command;
+
+use OCP\IUser;
+use OCP\IUserManager;
+use OCA\Files_Trashbin\Expiration;
+use OCA\Files_Trashbin\Helper;
+use OCA\Files_Trashbin\Trashbin;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class ExpireTrash extends Command {
+
+ /**
+ * @var Expiration
+ */
+ private $expiration;
+
+ /**
+ * @var IUserManager
+ */
+ private $userManager;
+
+ /**
+ * @param IUserManager|null $userManager
+ * @param Expiration|null $expiration
+ */
+ public function __construct(IUserManager $userManager = null,
+ Expiration $expiration = null) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->expiration = $expiration;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('trashbin:expire')
+ ->setDescription('Expires the users trashbin')
+ ->addArgument(
+ 'user_id',
+ InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
+ 'expires the trashbin of the given user(s), if no user is given the trash for all users will be expired'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+
+ $maxAge = $this->expiration->getMaxAgeAsTimestamp();
+ if (!$maxAge) {
+ $output->writeln("No expiry configured.");
+ return;
+ }
+
+ $users = $input->getArgument('user_id');
+ if (!empty($users)) {
+ foreach ($users as $user) {
+ if ($this->userManager->userExists($user)) {
+ $output->writeln("Remove deleted files of <info>$user</info>");
+ $userObject = $this->userManager->get($user);
+ $this->expireTrashForUser($userObject);
+ } else {
+ $output->writeln("<error>Unknown user $user</error>");
+ }
+ }
+ } else {
+ $p = new ProgressBar($output);
+ $p->start();
+ $this->userManager->callForAllUsers(function(IUser $user) use ($p) {
+ $p->advance();
+ $this->expireTrashForUser($user);
+ });
+ $p->finish();
+ $output->writeln('');
+ }
+ }
+
+ function expireTrashForUser(IUser $user) {
+ $uid = $user->getUID();
+ if ($user->getLastLogin() === 0 || !$this->setupFS($uid)) {
+ return;
+ }
+ $dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
+ Trashbin::deleteExpiredFiles($dirContent, $uid);
+ }
+
+ /**
+ * Act on behalf on trash item owner
+ * @param string $user
+ * @return boolean
+ */
+ protected function setupFS($user) {
+ \OC_Util::tearDownFS();
+ \OC_Util::setupFS($user);
+
+ // Check if this user has a trashbin directory
+ $view = new \OC\Files\View('/' . $user);
+ if (!$view->is_dir('/files_trashbin/files')) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/apps/files_versions/appinfo/register_command.php b/apps/files_versions/appinfo/register_command.php
index b991c72b944..bca869075aa 100644
--- a/apps/files_versions/appinfo/register_command.php
+++ b/apps/files_versions/appinfo/register_command.php
@@ -21,9 +21,14 @@
*/
+use OCA\Files_Versions\AppInfo\Application;
use OCA\Files_Versions\Command\CleanUp;
+use OCA\Files_Versions\Command\ExpireVersions;
+$app = new Application();
+$expiration = $app->getContainer()->query('Expiration');
$userManager = OC::$server->getUserManager();
$rootFolder = \OC::$server->getRootFolder();
/** @var Symfony\Component\Console\Application $application */
$application->add(new CleanUp($rootFolder, $userManager));
+$application->add(new ExpireVersions($userManager, $expiration));
diff --git a/apps/files_versions/lib/Command/ExpireVersions.php b/apps/files_versions/lib/Command/ExpireVersions.php
new file mode 100644
index 00000000000..f384420f22f
--- /dev/null
+++ b/apps/files_versions/lib/Command/ExpireVersions.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud GmbH.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Versions\Command;
+
+use OCA\Files_Versions\Expiration;
+use OCA\Files_Versions\Storage;
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class ExpireVersions extends Command {
+
+ /**
+ * @var Expiration
+ */
+ private $expiration;
+
+ /**
+ * @var IUserManager
+ */
+ private $userManager;
+
+ /**
+ * @param IUserManager|null $userManager
+ * @param Expiration|null $expiration
+ */
+ public function __construct(IUserManager $userManager = null,
+ Expiration $expiration = null) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->expiration = $expiration;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('versions:expire')
+ ->setDescription('Expires the users file versions')
+ ->addArgument(
+ 'user_id',
+ InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
+ 'expire file versions of the given user(s), if no user is given file versions for all users will be expired.'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+
+ $maxAge = $this->expiration->getMaxAgeAsTimestamp();
+ if (!$maxAge) {
+ $output->writeln("No expiry configured.");
+ return;
+ }
+
+ $users = $input->getArgument('user_id');
+ if (!empty($users)) {
+ foreach ($users as $user) {
+ if ($this->userManager->userExists($user)) {
+ $output->writeln("Remove deleted files of <info>$user</info>");
+ $userObject = $this->userManager->get($user);
+ $this->expireVersionsForUser($userObject);
+ } else {
+ $output->writeln("<error>Unknown user $user</error>");
+ }
+ }
+ } else {
+ $p = new ProgressBar($output);
+ $p->start();
+ $this->userManager->callForAllUsers(function(IUser $user) use ($p) {
+ $p->advance();
+ $this->expireVersionsForUser($user);
+ });
+ $p->finish();
+ $output->writeln('');
+ }
+ }
+
+ function expireVersionsForUser(IUser $user) {
+ $uid = $user->getUID();
+ if ($user->getLastLogin() === 0 || !$this->setupFS($uid)) {
+ return;
+ }
+ Storage::expireOlderThanMaxForUser($uid);
+ }
+
+ /**
+ * Act on behalf on versions item owner
+ * @param string $user
+ * @return boolean
+ */
+ protected function setupFS($user) {
+ \OC_Util::tearDownFS();
+ \OC_Util::setupFS($user);
+
+ // Check if this user has a version directory
+ $view = new \OC\Files\View('/' . $user);
+ if (!$view->is_dir('/files_versions')) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php
index e9e20c047aa..e6da74601ba 100644
--- a/build/integration/features/bootstrap/BasicStructure.php
+++ b/build/integration/features/bootstrap/BasicStructure.php
@@ -344,4 +344,28 @@ trait BasicStructure {
rmdir("../../core/skeleton/PARENT");
}
}
+
+ /**
+ * @BeforeScenario @local_storage
+ */
+ public static function removeFilesFromLocalStorageBefore(){
+ $dir = "./work/local_storage/";
+ $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
+ $ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ( $ri as $file ) {
+ $file->isDir() ? rmdir($file) : unlink($file);
+ }
+ }
+
+ /**
+ * @AfterScenario @local_storage
+ */
+ public static function removeFilesFromLocalStorageAfter(){
+ $dir = "./work/local_storage/";
+ $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
+ $ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ( $ri as $file ) {
+ $file->isDir() ? rmdir($file) : unlink($file);
+ }
+ }
}
diff --git a/build/integration/features/external-storage.feature b/build/integration/features/external-storage.feature
new file mode 100644
index 00000000000..9e53b01346e
--- /dev/null
+++ b/build/integration/features/external-storage.feature
@@ -0,0 +1,26 @@
+Feature: external-storage
+ Background:
+ Given using api version "1"
+ Given using dav path "remote.php/webdav"
+
+ @local_storage
+ Scenario: Share by link a file inside a local external storage
+ Given user "user0" exists
+ And user "user1" exists
+ And As an "user0"
+ And user "user0" created a folder "/local_storage/foo"
+ And User "user0" moved file "/textfile0.txt" to "/local_storage/foo/textfile0.txt"
+ And folder "/local_storage/foo" of user "user0" is shared with user "user1"
+ And As an "user1"
+ When creating a share with
+ | path | foo |
+ | shareType | 3 |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And Share fields of last share match with
+ | id | A_NUMBER |
+ | url | AN_URL |
+ | token | A_TOKEN |
+ | mimetype | httpd/unix-directory |
+
+
diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature
index 38ed5213b19..785b795bf35 100644
--- a/build/integration/features/provisioning-v1.feature
+++ b/build/integration/features/provisioning-v1.feature
@@ -295,6 +295,7 @@ Feature: provisioning
| theming |
| updatenotification |
| workflowengine |
+ | files_external |
Scenario: get app info
Given As an "admin"
@@ -304,19 +305,19 @@ Feature: provisioning
Scenario: enable an app
Given As an "admin"
- And app "files_external" is disabled
- When sending "POST" to "/cloud/apps/files_external"
+ And app "testing" is disabled
+ When sending "POST" to "/cloud/apps/testing"
Then the OCS status code should be "100"
And the HTTP status code should be "200"
- And app "files_external" is enabled
+ And app "testing" is enabled
Scenario: disable an app
Given As an "admin"
- And app "files_external" is enabled
- When sending "DELETE" to "/cloud/apps/files_external"
+ And app "testing" is enabled
+ When sending "DELETE" to "/cloud/apps/testing"
Then the OCS status code should be "100"
And the HTTP status code should be "200"
- And app "files_external" is disabled
+ And app "testing" is disabled
Scenario: disable an user
Given As an "admin"
diff --git a/build/integration/run.sh b/build/integration/run.sh
index eccb378eec4..cf42ed75e4c 100755
--- a/build/integration/run.sh
+++ b/build/integration/run.sh
@@ -36,12 +36,27 @@ echo $PHPPID_FED
export TEST_SERVER_URL="http://localhost:$PORT/ocs/"
export TEST_SERVER_FED_URL="http://localhost:$PORT_FED/ocs/"
+#Enable external storage app
+../../occ app:enable files_external
+
+mkdir -p work/local_storage
+OUTPUT_CREATE_STORAGE=`../../occ files_external:create local_storage local null::null -c datadir=./build/integration/work/local_storage`
+
+ID_STORAGE=`echo $OUTPUT_CREATE_STORAGE | awk {'print $5'}`
+
+../../occ files_external:option $ID_STORAGE enable_sharing true
+
vendor/bin/behat -f junit -f pretty $SCENARIO_TO_RUN
RESULT=$?
kill $PHPPID
kill $PHPPID_FED
+../../occ files_external:delete -y $ID_STORAGE
+
+#Disable external storage app
+../../occ app:disable files_external
+
if [ -z $HIDE_OC_LOGS ]; then
tail "../../data/nextcloud.log"
fi
diff --git a/core/ajax/preview.php b/core/ajax/preview.php
index 2894efdc8e3..6cfba6aef30 100644
--- a/core/ajax/preview.php
+++ b/core/ajax/preview.php
@@ -53,6 +53,8 @@ $info = \OC\Files\Filesystem::getFileInfo($file);
if (!$info instanceof OCP\Files\FileInfo || !$always && !\OC::$server->getPreviewManager()->isAvailable($info)) {
\OC_Response::setStatus(404);
+} else if (!$info->isReadable()) {
+ \OC_Response::setStatus(403);
} else {
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
$preview->setFile($file, $info);
diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js
index 08b892ce8bb..e1b9dba14af 100644
--- a/core/js/mimetypelist.js
+++ b/core/js/mimetypelist.js
@@ -65,6 +65,9 @@ OC.MimeTypeList={
"application/x-font": "image",
"application/x-gimp": "image",
"application/x-gzip": "package/x-generic",
+ "application/x-iwork-keynote-sffkey": "x-office/presentation",
+ "application/x-iwork-numbers-sffnumbers": "x-office/spreadsheet",
+ "application/x-iwork-pages-sffpages": "x-office/document",
"application/x-mobipocket-ebook": "text",
"application/x-perl": "text/code",
"application/x-photoshop": "image",
diff --git a/index.php b/index.php
index e42a0bbd7bc..8c3066d2409 100644
--- a/index.php
+++ b/index.php
@@ -25,10 +25,10 @@
*
*/
-// Show warning if a PHP version below 5.4.0 is used, this has to happen here
-// because base.php will already use 5.4 syntax.
-if (version_compare(PHP_VERSION, '5.4.0') === -1) {
- echo 'This version of ownCloud requires at least PHP 5.4.0<br/>';
+// Show warning if a PHP version below 5.6.0 is used, this has to happen here
+// because base.php will already use 5.6 syntax.
+if (version_compare(PHP_VERSION, '5.6.0') === -1) {
+ echo 'This version of Nextcloud requires at least PHP 5.6.0<br/>';
echo 'You are currently running ' . PHP_VERSION . '. Please update your PHP version.';
return;
}
diff --git a/lib/base.php b/lib/base.php
index 68eab7c4acf..fe7419e6ff3 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -922,6 +922,9 @@ class OC {
$request = \OC::$server->getRequest();
$requestPath = $request->getRawPathInfo();
+ if ($requestPath === '/heartbeat') {
+ return;
+ }
if (substr($requestPath, -3) !== '.js') { // we need these files during the upgrade
self::checkMaintenanceMode();
self::checkUpgrade();
diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php
index 46122f880cc..ba8a48381bd 100644
--- a/lib/private/AppFramework/Http/Request.php
+++ b/lib/private/AppFramework/Http/Request.php
@@ -485,6 +485,19 @@ class Request implements \ArrayAccess, \Countable, IRequest {
}
/**
+ * Whether the cookie checks are required
+ *
+ * @return bool
+ */
+ private function cookieCheckRequired() {
+ if($this->getCookie(session_name()) === null && $this->getCookie('oc_token') === null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
* Checks if the strict cookie has been sent with the request if the request
* is including any cookies.
*
@@ -492,7 +505,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @since 9.1.0
*/
public function passesStrictCookieCheck() {
- if(count($this->cookies) === 0) {
+ if(!$this->cookieCheckRequired()) {
return true;
}
if($this->getCookie('nc_sameSiteCookiestrict') === 'true'
@@ -510,7 +523,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @since 9.1.0
*/
public function passesLaxCookieCheck() {
- if(count($this->cookies) === 0) {
+ if(!$this->cookieCheckRequired()) {
return true;
}
if($this->getCookie('nc_sameSiteCookielax') === 'true') {
diff --git a/lib/private/Encryption/DecryptAll.php b/lib/private/Encryption/DecryptAll.php
index 6e309b5c892..b84395b9e17 100644
--- a/lib/private/Encryption/DecryptAll.php
+++ b/lib/private/Encryption/DecryptAll.php
@@ -210,6 +210,10 @@ class DecryptAll {
while ($root = array_pop($directories)) {
$content = $this->rootView->getDirectoryContent($root);
foreach ($content as $file) {
+ // only decrypt files owned by the user
+ if($file->getStorage()->instanceOfStorage('OC\Files\Storage\Shared')) {
+ continue;
+ }
$path = $root . '/' . $file['name'];
if ($this->rootView->is_dir($path)) {
$directories[] = $path;
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index ab58a976873..bd8343fa440 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -159,7 +159,8 @@ class UserMountCache implements IUserMountCache {
'mount_id' => $mount->getMountId()
], ['root_id', 'user_id']);
} else {
- $this->logger->error('Error getting storage info for mount at ' . $mount->getMountPoint());
+ // in some cases this is legitimate, like orphaned shares
+ $this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint());
}
}
diff --git a/lib/private/Preview.php b/lib/private/Preview.php
index 70b000a30ee..67838a8d4a3 100644
--- a/lib/private/Preview.php
+++ b/lib/private/Preview.php
@@ -763,7 +763,7 @@ class Preview {
$this->preview = null;
$fileInfo = $this->getFileInfo();
- if ($fileInfo === null || $fileInfo === false) {
+ if ($fileInfo === null || $fileInfo === false || !$fileInfo->isReadable()) {
return new \OC_Image();
}
diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php
index 11a343918c6..031c5ffd411 100644
--- a/lib/private/Security/Bruteforce/Throttler.php
+++ b/lib/private/Security/Bruteforce/Throttler.php
@@ -225,8 +225,11 @@ class Throttler {
* Will sleep for the defined amount of time
*
* @param string $ip
+ * @return int the time spent sleeping
*/
public function sleepDelay($ip) {
- usleep($this->getDelay($ip) * 1000);
+ $delay = $this->getDelay($ip);
+ usleep($delay * 1000);
+ return $delay;
}
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 3b357b69bcf..dec959820f8 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -309,8 +309,7 @@ class Session implements IUserSession, Emitter {
$password,
IRequest $request,
OC\Security\Bruteforce\Throttler $throttler) {
- $currentDelay = $throttler->getDelay($request->getRemoteAddress());
- $throttler->sleepDelay($request->getRemoteAddress());
+ $currentDelay = $throttler->sleepDelay($request->getRemoteAddress());
$isTokenPassword = $this->isTokenPassword($password);
if (!$isTokenPassword && $this->isTokenAuthEnforced()) {
diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json
index 8b47867447f..602f70393ae 100644
--- a/resources/config/mimetypealiases.dist.json
+++ b/resources/config/mimetypealiases.dist.json
@@ -65,6 +65,9 @@
"application/x-font": "image",
"application/x-gimp": "image",
"application/x-gzip": "package/x-generic",
+ "application/x-iwork-keynote-sffkey": "x-office/presentation",
+ "application/x-iwork-numbers-sffnumbers": "x-office/spreadsheet",
+ "application/x-iwork-pages-sffpages": "x-office/document",
"application/x-mobipocket-ebook": "text",
"application/x-perl": "text/code",
"application/x-photoshop": "image",
diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php
index a3433e558d8..420b73a22d9 100644
--- a/tests/lib/AppFramework/Http/RequestTest.php
+++ b/tests/lib/AppFramework/Http/RequestTest.php
@@ -1469,6 +1469,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookiestrict' => 'true',
],
],
@@ -1495,6 +1496,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookiestrict' => 'true',
'nc_sameSiteCookielax' => 'true',
],
@@ -1509,7 +1511,76 @@ class RequestTest extends \Test\TestCase {
$this->assertTrue($request->passesStrictCookieCheck());
}
- public function testFailsSRFCheckWithPostAndWithCookies() {
+ public function testPassesStrictCookieCheckWithRandomCookies() {
+ /** @var Request $request */
+ $request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
+ ->setMethods(['getScriptName'])
+ ->setConstructorArgs([
+ [
+ 'server' => [
+ 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
+ ],
+ 'cookies' => [
+ 'RandomCookie' => 'asdf',
+ ],
+ ],
+ $this->secureRandom,
+ $this->config,
+ $this->csrfTokenManager,
+ $this->stream
+ ])
+ ->getMock();
+
+ $this->assertTrue($request->passesStrictCookieCheck());
+ }
+
+ public function testFailsStrictCookieCheckWithSessionCookie() {
+ /** @var Request $request */
+ $request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
+ ->setMethods(['getScriptName'])
+ ->setConstructorArgs([
+ [
+ 'server' => [
+ 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
+ ],
+ 'cookies' => [
+ session_name() => 'asdf',
+ ],
+ ],
+ $this->secureRandom,
+ $this->config,
+ $this->csrfTokenManager,
+ $this->stream
+ ])
+ ->getMock();
+
+ $this->assertFalse($request->passesStrictCookieCheck());
+ }
+
+ public function testFailsStrictCookieCheckWithRememberMeCookie() {
+ /** @var Request $request */
+ $request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
+ ->setMethods(['getScriptName'])
+ ->setConstructorArgs([
+ [
+ 'server' => [
+ 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
+ ],
+ 'cookies' => [
+ 'oc_token' => 'asdf',
+ ],
+ ],
+ $this->secureRandom,
+ $this->config,
+ $this->csrfTokenManager,
+ $this->stream
+ ])
+ ->getMock();
+
+ $this->assertFalse($request->passesStrictCookieCheck());
+ }
+
+ public function testFailsCSRFCheckWithPostAndWithCookies() {
/** @var Request $request */
$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
->setMethods(['getScriptName'])
@@ -1519,6 +1590,7 @@ class RequestTest extends \Test\TestCase {
'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'foo' => 'bar',
],
],
@@ -1545,6 +1617,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookielax' => 'true',
],
],
@@ -1568,6 +1641,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookiestrict' => 'true',
],
],
@@ -1591,6 +1665,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookielax' => 'true',
],
],
@@ -1614,6 +1689,7 @@ class RequestTest extends \Test\TestCase {
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'cookies' => [
+ session_name() => 'asdf',
'nc_sameSiteCookiestrict' => 'true',
],
],
diff --git a/tests/lib/Encryption/DecryptAllTest.php b/tests/lib/Encryption/DecryptAllTest.php
index d7cf2fb7baf..ed86b743c3b 100644
--- a/tests/lib/Encryption/DecryptAllTest.php
+++ b/tests/lib/Encryption/DecryptAllTest.php
@@ -251,18 +251,29 @@ class DecryptAllTest extends TestCase {
->setMethods(['decryptFile'])
->getMock();
+ $storage = $this->getMockBuilder('OCP\Files\Storage')
+ ->disableOriginalConstructor()->getMock();
+
+
+ $sharedStorage = $this->getMockBuilder('OCP\Files\Storage')
+ ->disableOriginalConstructor()->getMock();
+
+ $sharedStorage->expects($this->once())->method('instanceOfStorage')
+ ->with('OC\Files\Storage\Shared')->willReturn(true);
+
$this->view->expects($this->at(0))->method('getDirectoryContent')
->with('/user1/files')->willReturn(
[
- new FileInfo('path', null, 'intPath', ['name' => 'foo', 'type'=>'dir'], null),
- new FileInfo('path', null, 'intPath', ['name' => 'bar', 'type'=>'file', 'encrypted'=>true], null)
+ new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type'=>'dir'], null),
+ new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type'=>'file', 'encrypted'=>true], null),
+ new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type'=>'file', 'encrypted'=>true], null),
]
);
$this->view->expects($this->at(3))->method('getDirectoryContent')
->with('/user1/files/foo')->willReturn(
[
- new FileInfo('path', null, 'intPath', ['name' => 'subfile', 'type'=>'file', 'encrypted'=>true], null)
+ new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type'=>'file', 'encrypted'=>true], null)
]
);
diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php
index 379c7e39442..4b8067117b1 100644
--- a/tests/lib/User/SessionTest.php
+++ b/tests/lib/User/SessionTest.php
@@ -371,7 +371,7 @@ class SessionTest extends \Test\TestCase {
->with('token_auth_enforced', false)
->will($this->returnValue(true));
$request
- ->expects($this->exactly(2))
+ ->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
@@ -379,7 +379,7 @@ class SessionTest extends \Test\TestCase {
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
- ->expects($this->once())
+ ->expects($this->any())
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
@@ -412,7 +412,7 @@ class SessionTest extends \Test\TestCase {
->method('set')
->with('app_password', 'I-AM-AN-APP-PASSWORD');
$request
- ->expects($this->exactly(2))
+ ->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
@@ -420,7 +420,7 @@ class SessionTest extends \Test\TestCase {
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
- ->expects($this->once())
+ ->expects($this->any())
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
@@ -459,7 +459,7 @@ class SessionTest extends \Test\TestCase {
->will($this->returnValue(true));
$request
- ->expects($this->exactly(2))
+ ->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
@@ -467,7 +467,7 @@ class SessionTest extends \Test\TestCase {
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
- ->expects($this->once())
+ ->expects($this->any())
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);