summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/js/files.js3
-rw-r--r--apps/files/lib/Command/Scan.php18
-rw-r--r--apps/files/tests/js/filesSpec.js4
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php2
-rw-r--r--apps/files_sharing/lib/MountProvider.php18
-rw-r--r--apps/files_sharing/templates/public.php2
-rw-r--r--apps/files_sharing/tests/Controller/ShareAPIControllerTest.php7
-rw-r--r--apps/files_sharing/tests/MountProviderTest.php22
-rw-r--r--apps/files_sharing/tests/js/publicAppSpec.js4
-rw-r--r--apps/theming/lib/ThemingDefaults.php9
-rw-r--r--build/integration/features/bootstrap/BasicStructure.php24
-rw-r--r--build/integration/features/bootstrap/WebDav.php19
-rw-r--r--build/integration/features/webdav-related.feature38
-rw-r--r--core/Command/Encryption/EncryptAll.php8
-rw-r--r--core/Command/InterruptedException.php26
-rw-r--r--core/Command/User/ResetPassword.php5
-rw-r--r--core/css/header.scss2
-rw-r--r--core/js/js.js8
-rw-r--r--core/js/sharedialogview.js2
-rw-r--r--core/js/tests/specHelper.js3
-rw-r--r--core/templates/installation.php16
-rw-r--r--core/templates/layout.user.php4
-rw-r--r--core/templates/login.php4
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/App/AppManager.php5
-rw-r--r--lib/private/Console/Application.php4
-rw-r--r--lib/private/Files/View.php11
-rw-r--r--lib/private/Group/Manager.php30
-rw-r--r--lib/private/Preview/Generator.php38
-rw-r--r--lib/private/Server.php2
-rw-r--r--lib/private/Share20/DefaultShareProvider.php4
-rw-r--r--lib/private/Share20/Manager.php13
-rw-r--r--lib/private/SystemTag/SystemTagManager.php3
-rw-r--r--lib/private/Template/JSConfigHelper.php1
-rwxr-xr-xlib/private/Template/ResourceLocator.php2
-rw-r--r--lib/private/User/Database.php9
-rw-r--r--lib/private/User/Session.php3
-rw-r--r--lib/private/legacy/files.php4
-rw-r--r--lib/public/Files/FileInfo.php6
-rw-r--r--settings/js/apps.js4
-rw-r--r--settings/templates/personal.php16
-rw-r--r--settings/templates/users/part.createuser.php6
-rw-r--r--tests/lib/App/ManagerTest.php25
-rw-r--r--tests/lib/Files/ViewTest.php2
-rw-r--r--tests/lib/Group/ManagerTest.php205
-rw-r--r--tests/lib/Preview/GeneratorTest.php6
-rw-r--r--tests/lib/Share20/DefaultShareProviderTest.php42
-rw-r--r--tests/lib/Share20/ManagerTest.php73
-rw-r--r--tests/lib/SystemTag/SystemTagManagerTest.php9
-rw-r--r--tests/lib/User/DatabaseTest.php19
51 files changed, 620 insertions, 172 deletions
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 99f888ce0f7..5b345a45b67 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -101,7 +101,10 @@
throw t('files', '"{name}" is an invalid file name.', {name: name});
} else if (trimmedName.length === 0) {
throw t('files', 'File name cannot be empty.');
+ } else if (OC.fileIsBlacklisted(trimmedName)) {
+ throw t('files', '"{name}" is not an allowed filetype', {name: name});
}
+
return true;
},
displayStorageWarnings: function() {
diff --git a/apps/files/lib/Command/Scan.php b/apps/files/lib/Command/Scan.php
index 0234fb435a7..24b47aca9a4 100644
--- a/apps/files/lib/Command/Scan.php
+++ b/apps/files/lib/Command/Scan.php
@@ -30,6 +30,7 @@ namespace OCA\Files\Command;
use Doctrine\DBAL\Connection;
use OC\Core\Command\Base;
+use OC\Core\Command\InterruptedException;
use OC\ForbiddenException;
use OCP\Files\StorageNotAvailableException;
use OCP\IDBConnection;
@@ -117,14 +118,14 @@ class Scan extends Base {
$output->writeln("\tFile <info>$path</info>");
$this->filesCounter += 1;
if ($this->hasBeenInterrupted()) {
- throw new \Exception('ctrl-c');
+ throw new InterruptedException();
}
});
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
$output->writeln("\tFolder <info>$path</info>");
$this->foldersCounter += 1;
if ($this->hasBeenInterrupted()) {
- throw new \Exception('ctrl-c');
+ throw new InterruptedException();
}
});
$scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) {
@@ -135,13 +136,13 @@ class Scan extends Base {
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function () use ($output) {
$this->filesCounter += 1;
if ($this->hasBeenInterrupted()) {
- throw new \Exception('ctrl-c');
+ throw new InterruptedException();
}
});
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function () use ($output) {
$this->foldersCounter += 1;
if ($this->hasBeenInterrupted()) {
- throw new \Exception('ctrl-c');
+ throw new InterruptedException();
}
});
}
@@ -161,11 +162,12 @@ class Scan extends Base {
} catch (ForbiddenException $e) {
$output->writeln("<error>Home storage for user $user not writable</error>");
$output->writeln("Make sure you're running the scan command only as the user the web server runs as");
+ } catch (InterruptedException $e) {
+ # exit the function if ctrl-c has been pressed
+ $output->writeln('Interrupted by user');
} catch (\Exception $e) {
- if ($e->getMessage() !== 'ctrl-c') {
- $output->writeln('<error>Exception while scanning: ' . $e->getMessage() . "\n" . $e->getTraceAsString() . '</error>');
- }
- return;
+ $output->writeln('<error>Exception during scan: ' . $e->getMessage() . '</error>');
+ $output->writeln('<error>' . $e->getTraceAsString() . '</error>');
}
}
diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js
index b7627d59fdf..5c3f68b2ba4 100644
--- a/apps/files/tests/js/filesSpec.js
+++ b/apps/files/tests/js/filesSpec.js
@@ -58,7 +58,9 @@ describe('OCA.Files.Files tests', function() {
' ..',
'.. ',
'. ',
- ' .'
+ ' .',
+ 'foo.part',
+ 'bar.filepart'
];
for ( var i = 0; i < fileNames.length; i++ ) {
var threwException = false;
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index 711970d0c84..78eef6c26bb 100644
--- a/apps/files_sharing/lib/Controller/ShareAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareAPIController.php
@@ -804,7 +804,7 @@ class ShareAPIController extends OCSController {
if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$sharedWith = $this->groupManager->get($share->getSharedWith());
$user = $this->userManager->get($this->currentUser);
- if ($user !== null && $sharedWith->inGroup($user)) {
+ if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
return true;
}
}
diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php
index f474190fc98..a02d6350499 100644
--- a/apps/files_sharing/lib/MountProvider.php
+++ b/apps/files_sharing/lib/MountProvider.php
@@ -173,7 +173,23 @@ class MountProvider implements IMountProvider {
if ($share->getTarget() !== $superShare->getTarget()) {
// adjust target, for database consistency
$share->setTarget($superShare->getTarget());
- $this->shareManager->moveShare($share, $user->getUID());
+ try {
+ $this->shareManager->moveShare($share, $user->getUID());
+ } catch (\InvalidArgumentException $e) {
+ // ignore as it is not important and we don't want to
+ // block FS setup
+
+ // the subsequent code anyway only uses the target of the
+ // super share
+
+ // such issue can usually happen when dealing with
+ // null groups which usually appear with group backend
+ // caching inconsistencies
+ $this->logger->debug(
+ 'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(),
+ ['app' => 'files_sharing']
+ );
+ }
}
if (!is_null($share->getNodeCacheEntry())) {
$superShare->setNodeCacheEntry($share->getNodeCacheEntry());
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index dd2ea855b0b..123a5cb4f53 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -120,7 +120,7 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size);
<input type="hidden" name="dir" id="dir" value="" />
<div class="hiddenuploadfield">
<input type="file" id="file_upload_start" class="hiddenuploadfield" name="files[]"
- data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" />
+ data-url="<?php p(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" />
</div>
<?php endif; ?>
<footer>
diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
index 97774081b6a..2bf9a40b2cc 100644
--- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
+++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
@@ -544,14 +544,19 @@ class ShareAPIControllerTest extends \Test\TestCase {
$this->groupManager->method('get')->will($this->returnValueMap([
['group', $group],
['group2', $group2],
+ ['groupnull', null],
]));
$this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
$share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
$share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
$share->method('getSharedWith')->willReturn('group2');
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
- $this->groupManager->method('get')->with('group2')->willReturn($group);
+ // null group
+ $share = $this->getMock('OCP\Share\IShare');
+ $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
+ $share->method('getSharedWith')->willReturn('groupnull');
$this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
$share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
diff --git a/apps/files_sharing/tests/MountProviderTest.php b/apps/files_sharing/tests/MountProviderTest.php
index 1c83d91d08f..b700d417ad4 100644
--- a/apps/files_sharing/tests/MountProviderTest.php
+++ b/apps/files_sharing/tests/MountProviderTest.php
@@ -269,6 +269,20 @@ class MountProviderTest extends \Test\TestCase {
['1', 100, 'user2', '/share2-renamed', 31],
],
],
+ // #9: share as outsider with "nullgroup" and "user1" where recipient renamed in between
+ [
+ [
+ [2, 100, 'user2', '/share2', 31],
+ ],
+ [
+ [1, 100, 'nullgroup', '/share2-renamed', 31],
+ ],
+ [
+ // use target of least recent share
+ ['1', 100, 'nullgroup', '/share2-renamed', 31],
+ ],
+ true
+ ],
];
}
@@ -284,7 +298,7 @@ class MountProviderTest extends \Test\TestCase {
* @param array $groupShares array of group share specs
* @param array $expectedShares array of expected supershare specs
*/
- public function testMergeShares($userShares, $groupShares, $expectedShares) {
+ public function testMergeShares($userShares, $groupShares, $expectedShares, $moveFails = false) {
$rootFolder = $this->createMock(IRootFolder::class);
$userManager = $this->createMock(IUserManager::class);
@@ -319,6 +333,12 @@ class MountProviderTest extends \Test\TestCase {
return new \OC\Share20\Share($rootFolder, $userManager);
}));
+ if ($moveFails) {
+ $this->shareManager->expects($this->any())
+ ->method('moveShare')
+ ->will($this->throwException(new \InvalidArgumentException()));
+ }
+
$mounts = $this->provider->getMountsForUser($this->user, $this->loader);
$this->assertCount(count($expectedShares), $mounts);
diff --git a/apps/files_sharing/tests/js/publicAppSpec.js b/apps/files_sharing/tests/js/publicAppSpec.js
index e8ec9899ecc..8ea339fd9de 100644
--- a/apps/files_sharing/tests/js/publicAppSpec.js
+++ b/apps/files_sharing/tests/js/publicAppSpec.js
@@ -125,6 +125,10 @@ describe('OCA.Sharing.PublicApp tests', function() {
expect(fileList.getAjaxUrl('test', {a:1, b:'x y'}))
.toEqual(OC.webroot + '/index.php/apps/files_sharing/ajax/test.php?a=1&b=x%20y&t=sh4tok');
});
+ it('returns correct download URL for downloading everything', function() {
+ expect(fileList.getDownloadUrl())
+ .toEqual(OC.webroot + '/index.php/s/sh4tok/download?path=%2Fsubdir');
+ });
});
describe('Upload Url', function() {
var fileList;
diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php
index 36f19157637..20625116213 100644
--- a/apps/theming/lib/ThemingDefaults.php
+++ b/apps/theming/lib/ThemingDefaults.php
@@ -28,6 +28,7 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Files\IRootFolder;
+use OCP\Util;
class ThemingDefaults extends \OC_Defaults {
@@ -81,7 +82,7 @@ class ThemingDefaults extends \OC_Defaults {
}
public function getName() {
- return $this->config->getAppValue('theming', 'name', $this->name);
+ return strip_tags($this->config->getAppValue('theming', 'name', $this->name));
}
public function getHTMLName() {
@@ -89,11 +90,11 @@ class ThemingDefaults extends \OC_Defaults {
}
public function getTitle() {
- return $this->config->getAppValue('theming', 'name', $this->name);
+ return $this->getName();
}
public function getEntity() {
- return $this->config->getAppValue('theming', 'name', $this->name);
+ return $this->getName();
}
public function getBaseUrl() {
@@ -101,7 +102,7 @@ class ThemingDefaults extends \OC_Defaults {
}
public function getSlogan() {
- return $this->config->getAppValue('theming', 'slogan', $this->slogan);
+ return Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan));
}
public function getShortFooter() {
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php
index 8e1fcf86ba1..8961efc6f31 100644
--- a/build/integration/features/bootstrap/BasicStructure.php
+++ b/build/integration/features/bootstrap/BasicStructure.php
@@ -353,6 +353,30 @@ trait BasicStructure {
fclose($file);
}
+ public function createFileWithText($name, $text){
+ $file = fopen("work/" . "$name", 'w');
+ fwrite($file, $text);
+ fclose($file);
+ }
+
+ /**
+ * @Given file :filename of size :size is created in local storage
+ * @param string $filename
+ * @param string $size
+ */
+ public function fileIsCreatedInLocalStorageWithSize($filename, $size) {
+ $this->createFileSpecificSize("local_storage/$filename", $size);
+ }
+
+ /**
+ * @Given file :filename with text :text is created in local storage
+ * @param string $filename
+ * @param string $text
+ */
+ public function fileIsCreatedInLocalStorageWithText($filename, $text) {
+ $this->createFileWithText("local_storage/$filename", $text);
+ }
+
/**
* @When User :user empties trashbin
* @param string $user
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index 680d8f96e7c..0a75ff96732 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -729,4 +729,23 @@ trait WebDav {
}
}
+ /**
+ * @When /^User "([^"]*)" deletes everything from folder "([^"]*)"$/
+ * @param string $user
+ * @param string $folder
+ */
+ public function userDeletesEverythingInFolder($user, $folder) {
+ $elementList = $this->listFolder($user, $folder, 1);
+ $elementListKeys = array_keys($elementList);
+ array_shift($elementListKeys);
+ $davPrefix = "/" . $this->getDavFilesPath($user);
+ foreach($elementListKeys as $element) {
+ if (substr($element, 0, strlen($davPrefix)) == $davPrefix) {
+ $element = substr($element, strlen($davPrefix));
+ }
+ $this->userDeletesFile($user, "element", $element);
+ }
+ }
+
+
}
diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature
index c3aa6145527..775bf2ca882 100644
--- a/build/integration/features/webdav-related.feature
+++ b/build/integration/features/webdav-related.feature
@@ -479,3 +479,41 @@ Feature: webdav-related
When as "user0" gets properties of folder "/test_folder:5" with
|{DAV:}resourcetype|
Then the single response should contain a property "{DAV:}resourcetype" with value "{DAV:}collection"
+
+ Scenario: Removing everything of a folder
+ Given using old dav path
+ And As an "admin"
+ And user "user0" exists
+ And As an "user0"
+ And User "user0" moves file "/welcome.txt" to "/FOLDER/welcome.txt"
+ And user "user0" created a folder "/FOLDER/SUBFOLDER"
+ And User "user0" copies file "/textfile0.txt" to "/FOLDER/SUBFOLDER/testfile0.txt"
+ When User "user0" deletes everything from folder "/FOLDER/"
+ Then user "user0" should see following elements
+ | /FOLDER/ |
+ | /PARENT/ |
+ | /PARENT/parent.txt |
+ | /textfile0.txt |
+ | /textfile1.txt |
+ | /textfile2.txt |
+ | /textfile3.txt |
+ | /textfile4.txt |
+
+ Scenario: Removing everything of a folder using new dav path
+ Given using new dav path
+ And As an "admin"
+ And user "user0" exists
+ And As an "user0"
+ And User "user0" moves file "/welcome.txt" to "/FOLDER/welcome.txt"
+ And user "user0" created a folder "/FOLDER/SUBFOLDER"
+ And User "user0" copies file "/textfile0.txt" to "/FOLDER/SUBFOLDER/testfile0.txt"
+ When User "user0" deletes everything from folder "/FOLDER/"
+ Then user "user0" should see following elements
+ | /FOLDER/ |
+ | /PARENT/ |
+ | /PARENT/parent.txt |
+ | /textfile0.txt |
+ | /textfile1.txt |
+ | /textfile2.txt |
+ | /textfile3.txt |
+ | /textfile4.txt |
diff --git a/core/Command/Encryption/EncryptAll.php b/core/Command/Encryption/EncryptAll.php
index 3a0c88c0798..584bc8a70c7 100644
--- a/core/Command/Encryption/EncryptAll.php
+++ b/core/Command/Encryption/EncryptAll.php
@@ -109,10 +109,10 @@ class EncryptAll extends Command {
}
$output->writeln("\n");
- $output->writeln('You are about to start to encrypt all files stored in your ownCloud.');
- $output->writeln('It will depend on the encryption module you use which files get encrypted.');
- $output->writeln('Depending on the number and size of your files this can take some time');
- $output->writeln('Please make sure that no user access his files during this process!');
+ $output->writeln('You are about to encrypt all files stored in your Nextcloud installation.');
+ $output->writeln('Depending on the number of available files, and their size, this may take quite some time.');
+ $output->writeln('Please ensure that no user accesses their files during this time!');
+ $output->writeln('Note: The encryption module you use determines which files get encrypted.');
$output->writeln('');
$question = new ConfirmationQuestion('Do you really want to continue? (y/n) ', false);
if ($this->questionHelper->ask($input, $output, $question)) {
diff --git a/core/Command/InterruptedException.php b/core/Command/InterruptedException.php
new file mode 100644
index 00000000000..ef81b5d9393
--- /dev/null
+++ b/core/Command/InterruptedException.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2017, ownCloud, Inc.
+ * @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 OC\Core\Command;
+
+/**
+ * Exception for when the user hit ctrl-c
+ */
+class InterruptedException extends \Exception {}
diff --git a/core/Command/User/ResetPassword.php b/core/Command/User/ResetPassword.php
index 3388ef6a1bd..56260e9714a 100644
--- a/core/Command/User/ResetPassword.php
+++ b/core/Command/User/ResetPassword.php
@@ -100,6 +100,11 @@ class ResetPassword extends Command {
$question->setHidden(true);
$password = $helper->ask($input, $output, $question);
+ if ($password === null) {
+ $output->writeln("<error>Password cannot be empty!</error>");
+ return 1;
+ }
+
$question = new Question('Confirm the new password: ');
$question->setHidden(true);
$confirm = $helper->ask($input, $output, $question);
diff --git a/core/css/header.scss b/core/css/header.scss
index b04d7e917e2..fd2da104c38 100644
--- a/core/css/header.scss
+++ b/core/css/header.scss
@@ -323,7 +323,7 @@ nav {
}
/* Apps management */
-#apps-management {
+.apps-management {
min-height: initial;
height: initial;
margin: 0;
diff --git a/core/js/js.js b/core/js/js.js
index 5c737d41793..8c6fc0d9c07 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -225,6 +225,14 @@ var OCP = {},
},
/**
+ * Check if a user file is allowed to be handled.
+ * @param {string} file to check
+ */
+ fileIsBlacklisted: function(file) {
+ return !!(file.match(oc_config.blacklist_files_regex));
+ },
+
+ /**
* Redirect to the target URL, can also be used for downloads.
* @param {string} targetURL URL to redirect to
*/
diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js
index 58dd706fb1f..47471955563 100644
--- a/core/js/sharedialogview.js
+++ b/core/js/sharedialogview.js
@@ -120,6 +120,8 @@
'_onSelectRecipient',
'onShareWithFieldChanged'
);
+
+ OC.Plugins.attach('OCA.Share.ShareDialogView', this);
},
onShareWithFieldChanged: function() {
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index 7897a2f2842..a411ade7dea 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -94,7 +94,8 @@ window.oc_appswebroots = {
};
window.oc_config = {
session_lifetime: 600 * 1000,
- session_keepalive: false
+ session_keepalive: false,
+ blacklist_files_regex: '\.(part|filepart)$',
};
window.oc_appconfig = {
core: {}
diff --git a/core/templates/installation.php b/core/templates/installation.php
index 058049d8946..6a0e3f93857 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -41,14 +41,14 @@ script('core', [
<input type="text" name="adminlogin" id="adminlogin"
placeholder="<?php p($l->t( 'Username' )); ?>"
value="<?php p($_['adminlogin']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" autofocus required>
+ autocomplete="off" autocapitalize="none" autocorrect="off" autofocus required>
<label for="adminlogin" class="infield"><?php p($l->t( 'Username' )); ?></label>
</p>
<p class="groupbottom">
<input type="password" name="adminpass" data-typetoggle="#show" id="adminpass"
placeholder="<?php p($l->t( 'Password' )); ?>"
value="<?php p($_['adminpass']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" required>
+ autocomplete="off" autocapitalize="none" autocorrect="off" required>
<label for="adminpass" class="infield"><?php p($l->t( 'Password' )); ?></label>
<input type="checkbox" id="show" name="show">
<label for="show"></label>
@@ -68,7 +68,7 @@ script('core', [
<input type="text" name="directory" id="directory"
placeholder="<?php p(OC::$SERVERROOT.'/data'); ?>"
value="<?php p($_['directory']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off">
+ autocomplete="off" autocapitalize="none" autocorrect="off">
</div>
</fieldset>
<?php endif; ?>
@@ -105,13 +105,13 @@ script('core', [
<input type="text" name="dbuser" id="dbuser"
placeholder="<?php p($l->t( 'Database user' )); ?>"
value="<?php p($_['dbuser']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off">
+ autocomplete="off" autocapitalize="none" autocorrect="off">
</p>
<p class="groupmiddle">
<input type="password" name="dbpass" id="dbpass" data-typetoggle="#dbpassword-toggle"
placeholder="<?php p($l->t( 'Database password' )); ?>"
value="<?php p($_['dbpass']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off">
+ autocomplete="off" autocapitalize="none" autocorrect="off">
<label for="dbpass" class="infield"><?php p($l->t( 'Database password' )); ?></label>
<input type="checkbox" id="dbpassword-toggle" name="dbpassword-toggle">
<label for="dbpassword-toggle"></label>
@@ -121,7 +121,7 @@ script('core', [
<input type="text" name="dbname" id="dbname"
placeholder="<?php p($l->t( 'Database name' )); ?>"
value="<?php p($_['dbname']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off"
+ autocomplete="off" autocapitalize="none" autocorrect="off"
pattern="[0-9a-zA-Z$_-]+">
</p>
<?php if($_['hasOracle']): ?>
@@ -131,7 +131,7 @@ script('core', [
<input type="text" name="dbtablespace" id="dbtablespace"
placeholder="<?php p($l->t( 'Database tablespace' )); ?>"
value="<?php p($_['dbtablespace']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off">
+ autocomplete="off" autocapitalize="none" autocorrect="off">
</p>
</div>
<?php endif; ?>
@@ -140,7 +140,7 @@ script('core', [
<input type="text" name="dbhost" id="dbhost"
placeholder="<?php p($l->t( 'Database host' )); ?>"
value="<?php p($_['dbhost']); ?>"
- autocomplete="off" autocapitalize="off" autocorrect="off">
+ autocomplete="off" autocapitalize="none" autocorrect="off">
</p>
<p class="info">
<?php p($l->t( 'Please specify the port number along with the host name (e.g., localhost:5432).' )); ?>
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 1abb263edf8..adeeaf03797 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -81,7 +81,7 @@
</a>
</li>
<?php if(OC_User::isAdminUser(OC_User::getUser())): ?>
- <li id="apps-management" <?php if(count($_['navigation'])>$headerIconCount-1): ?>class="hidden"<?php endif; ?>>
+ <li <?php if(count($_['navigation'])>$headerIconCount-1): ?> class="hidden apps-management"<?php else: ?> class="apps-management" <?php endif; ?>>
<a href="<?php print_unescaped(\OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')); ?>" tabindex="4"
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
<img src="<?php print_unescaped(image_path('settings', 'apps.svg') . '?v=' . $_['versionHash']); ?>" />
@@ -119,7 +119,7 @@
/* show "More apps" link to app administration directly in app navigation, as last entry */
if(OC_User::isAdminUser(OC_User::getUser())):
?>
- <li id="apps-management">
+ <li class="apps-management">
<a href="<?php print_unescaped(\OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')); ?>" tabindex="4"
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
<svg width="32" height="32" viewBox="0 0 32 32" class="app-icon">
diff --git a/core/templates/login.php b/core/templates/login.php
index 221242c0dcb..352893bd0dc 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -43,7 +43,7 @@ script('core', [
placeholder="<?php p($l->t('Username or email')); ?>"
value="<?php p($_['loginName']); ?>"
<?php p($_['user_autofocus'] ? 'autofocus' : ''); ?>
- autocomplete="on" autocapitalize="off" autocorrect="off" required>
+ autocomplete="on" autocapitalize="none" autocorrect="off" required>
<label for="user" class="infield"><?php p($l->t('Username or email')); ?></label>
</p>
@@ -51,7 +51,7 @@ script('core', [
<input type="password" name="password" id="password" value=""
placeholder="<?php p($l->t('Password')); ?>"
<?php p($_['user_autofocus'] ? '' : 'autofocus'); ?>
- autocomplete="on" autocapitalize="off" autocorrect="off" required>
+ autocomplete="on" autocapitalize="off" autocorrect="none" required>
<label for="password" class="infield"><?php p($l->t('Password')); ?></label>
</p>
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index c87bcce194f..d0d0898d0bd 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -407,6 +407,7 @@ return array(
'OC\\Core\\Command\\Integrity\\CheckCore' => $baseDir . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => $baseDir . '/core/Command/Integrity/SignApp.php',
'OC\\Core\\Command\\Integrity\\SignCore' => $baseDir . '/core/Command/Integrity/SignCore.php',
+ 'OC\\Core\\Command\\InterruptedException' => $baseDir . '/core/Command/InterruptedException.php',
'OC\\Core\\Command\\L10n\\CreateJs' => $baseDir . '/core/Command/L10n/CreateJs.php',
'OC\\Core\\Command\\Log\\File' => $baseDir . '/core/Command/Log/File.php',
'OC\\Core\\Command\\Log\\Manage' => $baseDir . '/core/Command/Log/Manage.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index eb7188b69b3..7b937bd132c 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -437,6 +437,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Command\\Integrity\\CheckCore' => __DIR__ . '/../../..' . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => __DIR__ . '/../../..' . '/core/Command/Integrity/SignApp.php',
'OC\\Core\\Command\\Integrity\\SignCore' => __DIR__ . '/../../..' . '/core/Command/Integrity/SignCore.php',
+ 'OC\\Core\\Command\\InterruptedException' => __DIR__ . '/../../..' . '/core/Command/InterruptedException.php',
'OC\\Core\\Command\\L10n\\CreateJs' => __DIR__ . '/../../..' . '/core/Command/L10n/CreateJs.php',
'OC\\Core\\Command\\Log\\File' => __DIR__ . '/../../..' . '/core/Command/Log/File.php',
'OC\\Core\\Command\\Log\\Manage' => __DIR__ . '/../../..' . '/core/Command/Log/Manage.php',
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 6b819ef7ac1..6c1f5ba6940 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -32,6 +32,7 @@
namespace OC\App;
use OCP\App\AppPathNotFoundException;
+use OC_App;
use OCP\App\IAppManager;
use OCP\App\ManagerEvent;
use OCP\IAppConfig;
@@ -210,8 +211,12 @@ class AppManager implements IAppManager {
* Enable an app for every user
*
* @param string $appId
+ * @throws \Exception
*/
public function enableApp($appId) {
+ if(OC_App::getAppPath($appId) === false) {
+ throw new \Exception("$appId can't be enabled since it is not installed.");
+ }
$this->installedAppsCache[$appId] = 'yes';
$this->appConfig->setValue($appId, 'enabled', 'yes');
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index 7d2f03d593e..693381ea2b4 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -37,6 +37,7 @@ use Symfony\Component\Console\Application as SymfonyApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Application {
@@ -97,7 +98,8 @@ class Application {
throw new NeedsUpdateException();
} elseif ($this->config->getSystemValue('maintenance', false)) {
if ($input->getArgument('command') !== '_completion') {
- $output->writeln("Nextcloud is in maintenance mode - no apps have been loaded");
+ $errOutput = $output->getErrorOutput();
+ $errOutput->writeln('<comment>Nextcloud is in maintenance mode - no app have been loaded</comment>' . PHP_EOL);
}
} else {
OC_App::loadApps();
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 6ffb5edff3e..506128d7fcd 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -96,8 +96,12 @@ class View {
private $updaterEnabled = true;
+ /** @var \OC\User\Manager */
private $userManager;
+ /** @var \OCP\ILogger */
+ private $logger;
+
/**
* @param string $root
* @throws \Exception If $root contains an invalid path
@@ -114,6 +118,7 @@ class View {
$this->lockingProvider = \OC::$server->getLockingProvider();
$this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider);
$this->userManager = \OC::$server->getUserManager();
+ $this->logger = \OC::$server->getLogger();
}
public function getAbsolutePath($path = '/') {
@@ -2068,6 +2073,12 @@ class View {
$parts = explode('/', trim($path, '/'), 3);
// "$user", "files", "path/to/dir"
if (!isset($parts[1]) || $parts[1] !== 'files') {
+ $this->logger->error(
+ '$absolutePath must be relative to "files", value is "%s"',
+ [
+ $absolutePath
+ ]
+ );
throw new \InvalidArgumentException('$absolutePath must be relative to "files"');
}
if (isset($parts[2])) {
diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php
index 944598a8296..40009dbfd80 100644
--- a/lib/private/Group/Manager.php
+++ b/lib/private/Group/Manager.php
@@ -37,7 +37,10 @@ namespace OC\Group;
use OC\Hooks\PublicEmitter;
use OCP\GroupInterface;
+use OCP\IGroup;
use OCP\IGroupManager;
+use OCP\ILogger;
+use OCP\IUser;
/**
* Class Manager
@@ -78,11 +81,16 @@ class Manager extends PublicEmitter implements IGroupManager {
/** @var \OC\SubAdmin */
private $subAdmin = null;
+ /** @var ILogger */
+ private $logger;
+
/**
* @param \OC\User\Manager $userManager
+ * @param ILogger $logger
*/
- public function __construct(\OC\User\Manager $userManager) {
+ public function __construct(\OC\User\Manager $userManager, ILogger $logger) {
$this->userManager = $userManager;
+ $this->logger = $logger;
$cachedGroups = & $this->cachedGroups;
$cachedUserGroups = & $this->cachedUserGroups;
$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
@@ -186,7 +194,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @return bool
*/
public function groupExists($gid) {
- return !is_null($this->get($gid));
+ return $this->get($gid) instanceof IGroup;
}
/**
@@ -194,7 +202,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @return \OC\Group\Group
*/
public function createGroup($gid) {
- if ($gid === '' || is_null($gid)) {
+ if ($gid === '' || $gid === null) {
return false;
} else if ($group = $this->get($gid)) {
return $group;
@@ -223,7 +231,12 @@ class Manager extends PublicEmitter implements IGroupManager {
foreach ($this->backends as $backend) {
$groupIds = $backend->getGroups($search, $limit, $offset);
foreach ($groupIds as $groupId) {
- $groups[$groupId] = $this->get($groupId);
+ $aGroup = $this->get($groupId);
+ if ($aGroup instanceof IGroup) {
+ $groups[$groupId] = $aGroup;
+ } else {
+ $this->logger->debug('Group "' . $groupId . '" was returned by search but not found through direct access', ['app' => 'core']);
+ }
}
if (!is_null($limit) and $limit <= 0) {
return array_values($groups);
@@ -237,7 +250,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @return \OC\Group\Group[]
*/
public function getUserGroups($user) {
- if (is_null($user)) {
+ if (!$user instanceof IUser) {
return [];
}
return $this->getUserIdGroups($user->getUID());
@@ -256,7 +269,12 @@ class Manager extends PublicEmitter implements IGroupManager {
$groupIds = $backend->getUserGroups($uid);
if (is_array($groupIds)) {
foreach ($groupIds as $groupId) {
- $groups[$groupId] = $this->get($groupId);
+ $aGroup = $this->get($groupId);
+ if ($aGroup instanceof IGroup) {
+ $groups[$groupId] = $aGroup;
+ } else {
+ $this->logger->debug('User "' . $uid . '" belongs to deleted group: "' . $groupId . '"', ['app' => 'core']);
+ }
}
}
}
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 32a732d8580..fd75e51b638 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -26,6 +26,7 @@ namespace OC\Preview;
use OCP\Files\File;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
@@ -111,6 +112,11 @@ class Generator {
// Calculate the preview size
list($width, $height) = $this->calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHeight);
+ // No need to generate a preview that is just the max preview
+ if ($width === $maxWidth && $height === $maxHeight) {
+ return $maxPreview;
+ }
+
// Try to get a cached preview. Else generate (and store) one
try {
$file = $this->getCachedPreview($previewFolder, $width, $height, $crop);
@@ -158,9 +164,13 @@ class Generator {
continue;
}
- $path = strval($preview->width()) . '-' . strval($preview->height()) . '-max.png';
- $file = $previewFolder->newFile($path);
- $file->putContent($preview->data());
+ $path = (string)$preview->width() . '-' . (string)$preview->height() . '-max.png';
+ try {
+ $file = $previewFolder->newFile($path);
+ $file->putContent($preview->data());
+ } catch (NotPermittedException $e) {
+ throw new NotFoundException();
+ }
return $file;
}
@@ -185,7 +195,7 @@ class Generator {
* @return string
*/
private function generatePath($width, $height, $crop) {
- $path = strval($width) . '-' . strval($height);
+ $path = (string)$width . '-' . (string)$height;
if ($crop) {
$path .= '-crop';
}
@@ -246,18 +256,18 @@ class Generator {
/*
* Scale to the nearest power of two
*/
- $pow2height = pow(2, ceil(log($height) / log(2)));
- $pow2width = pow(2, ceil(log($width) / log(2)));
+ $pow2height = 2 ** ceil(log($height) / log(2));
+ $pow2width = 2 ** ceil(log($width) / log(2));
$ratioH = $height / $pow2height;
$ratioW = $width / $pow2width;
if ($ratioH < $ratioW) {
$width = $pow2width;
- $height = $height / $ratioW;
+ $height /= $ratioW;
} else {
$height = $pow2height;
- $width = $width / $ratioH;
+ $width /= $ratioH;
}
}
@@ -268,12 +278,12 @@ class Generator {
if ($height > $maxHeight) {
$ratio = $height / $maxHeight;
$height = $maxHeight;
- $width = $width / $ratio;
+ $width /= $ratio;
}
if ($width > $maxWidth) {
$ratio = $width / $maxWidth;
$width = $maxWidth;
- $height = $height / $ratio;
+ $height /= $ratio;
}
return [(int)round($width), (int)round($height)];
@@ -316,8 +326,12 @@ class Generator {
}
$path = $this->generatePath($width, $height, $crop);
- $file = $previewFolder->newFile($path);
- $file->putContent($preview->data());
+ try {
+ $file = $previewFolder->newFile($path);
+ $file->putContent($preview->data());
+ } catch (NotPermittedException $e) {
+ throw new NotFoundException();
+ }
return $file;
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 24cd8b38684..dbec71457ef 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -227,7 +227,7 @@ class Server extends ServerContainer implements IServerContainer {
return new \OC\User\Manager($config);
});
$this->registerService('GroupManager', function (Server $c) {
- $groupManager = new \OC\Group\Manager($this->getUserManager());
+ $groupManager = new \OC\Group\Manager($this->getUserManager(), $this->getLogger());
$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
\OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
});
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index fe6472c31a0..e4ae26be13d 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -329,6 +329,10 @@ class DefaultShareProvider implements IShareProvider {
$group = $this->groupManager->get($share->getSharedWith());
$user = $this->userManager->get($recipient);
+ if (is_null($group)) {
+ throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
+ }
+
if (!$group->inGroup($user)) {
throw new ProviderException('Recipient not in receiving group');
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 3b565d1ba8c..e0457bba437 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -398,10 +398,12 @@ class Manager implements IManager {
// The share is already shared with this user via a group share
if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$group = $this->groupManager->get($existingShare->getSharedWith());
- $user = $this->userManager->get($share->getSharedWith());
+ if (!is_null($group)) {
+ $user = $this->userManager->get($share->getSharedWith());
- if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
- throw new \Exception('Path already shared with this user');
+ if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
+ throw new \Exception('Path already shared with this user');
+ }
}
}
}
@@ -423,7 +425,7 @@ class Manager implements IManager {
if ($this->shareWithGroupMembersOnly()) {
$sharedBy = $this->userManager->get($share->getSharedBy());
$sharedWith = $this->groupManager->get($share->getSharedWith());
- if (!$sharedWith->inGroup($sharedBy)) {
+ if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
throw new \Exception('Only sharing within your own groups is allowed');
}
}
@@ -891,6 +893,9 @@ class Manager implements IManager {
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$sharedWith = $this->groupManager->get($share->getSharedWith());
+ if (is_null($sharedWith)) {
+ throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
+ }
$recipient = $this->userManager->get($recipientId);
if (!$sharedWith->inGroup($recipient)) {
throw new \InvalidArgumentException('Invalid recipient');
diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php
index 7c21c0e004e..d0854e885eb 100644
--- a/lib/private/SystemTag/SystemTagManager.php
+++ b/lib/private/SystemTag/SystemTagManager.php
@@ -400,6 +400,9 @@ class SystemTagManager implements ISystemTagManager {
'gid' => $query->createParameter('gid'),
]);
foreach ($groupIds as $groupId) {
+ if ($groupId === '') {
+ continue;
+ }
$query->setParameter('gid', $groupId);
$query->execute();
}
diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php
index 6bf08dcdada..ca45bbee9c6 100644
--- a/lib/private/Template/JSConfigHelper.php
+++ b/lib/private/Template/JSConfigHelper.php
@@ -209,6 +209,7 @@ class JSConfigHelper {
'modRewriteWorking' => ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'),
'sharing.maxAutocompleteResults' => intval($this->config->getSystemValue('sharing.maxAutocompleteResults', 0)),
'sharing.minSearchStringLength' => intval($this->config->getSystemValue('sharing.minSearchStringLength', 0)),
+ 'blacklist_files_regex' => \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX,
]),
"oc_appconfig" => json_encode([
'core' => [
diff --git a/lib/private/Template/ResourceLocator.php b/lib/private/Template/ResourceLocator.php
index 9015bf5d97c..e82a77ba65f 100755
--- a/lib/private/Template/ResourceLocator.php
+++ b/lib/private/Template/ResourceLocator.php
@@ -84,7 +84,7 @@ abstract class ResourceLocator {
$this->doFindTheme($resource);
} catch (ResourceNotFoundException $e) {
$resourceApp = substr($resource, 0, strpos($resource, '/'));
- $this->logger->debug('Could not find resource file "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
+ $this->logger->debug('Could not find resource file in theme "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
}
}
}
diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php
index 060953c3009..ec463ba91dd 100644
--- a/lib/private/User/Database.php
+++ b/lib/private/User/Database.php
@@ -234,7 +234,7 @@ class Database extends Backend implements IUserBackend {
/**
* Load an user in the cache
* @param string $uid the username
- * @return boolean
+ * @return boolean true if user was found, false otherwise
*/
private function loadUser($uid) {
if (!isset($this->cache[$uid])) {
@@ -254,9 +254,14 @@ class Database extends Backend implements IUserBackend {
$this->cache[$uid] = false;
- while ($row = $result->fetchRow()) {
+ // "uid" is primary key, so there can only be a single result
+ if ($row = $result->fetchRow()) {
$this->cache[$uid]['uid'] = $row['uid'];
$this->cache[$uid]['displayname'] = $row['displayname'];
+ $result->closeCursor();
+ } else {
+ $result->closeCursor();
+ return false;
}
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index c03cbd5891b..4980318b554 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -14,6 +14,7 @@
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Felix Rupp <kontakt@felixrupp.com>
*
* @license AGPL-3.0
*
@@ -70,6 +71,7 @@ use Symfony\Component\EventDispatcher\GenericEvent;
* - preRememberedLogin(string $uid)
* - postRememberedLogin(\OC\User\User $user)
* - logout()
+ * - postLogout()
*
* @package OC\User
*/
@@ -796,6 +798,7 @@ class Session implements IUserSession, Emitter {
$this->setToken(null);
$this->unsetMagicInCookie();
$this->session->clear();
+ $this->manager->emit('\OC\User', 'postLogout');
}
/**
diff --git a/lib/private/legacy/files.php b/lib/private/legacy/files.php
index ed3aa719409..017691805c9 100644
--- a/lib/private/legacy/files.php
+++ b/lib/private/legacy/files.php
@@ -264,12 +264,12 @@ class OC_Files {
if (\OC\Files\Filesystem::isReadable($filename)) {
self::sendHeaders($filename, $name, $rangeArray);
} elseif (!\OC\Files\Filesystem::file_exists($filename)) {
- header("HTTP/1.0 404 Not Found");
+ header("HTTP/1.1 404 Not Found");
$tmpl = new OC_Template('', '404', 'guest');
$tmpl->printPage();
exit();
} else {
- header("HTTP/1.0 403 Forbidden");
+ header("HTTP/1.1 403 Forbidden");
die('403 Forbidden');
}
if (isset($params['head']) && $params['head']) {
diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php
index b6718efba34..8eeb8df08ce 100644
--- a/lib/public/Files/FileInfo.php
+++ b/lib/public/Files/FileInfo.php
@@ -64,6 +64,12 @@ interface FileInfo {
const MIMETYPE_FOLDER = 'httpd/unix-directory';
/**
+ * @const \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX Return regular expression to test filenames against (blacklisting)
+ * @since 12.0.0
+ */
+ const BLACKLIST_FILES_REGEX = '\.(part|filepart)$';
+
+ /**
* Get the Etag of the file or folder
*
* @return string
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 8be18c4e9c0..d2f26578a7c 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -541,10 +541,10 @@ OC.Settings.Apps = OC.Settings.Apps || {
if (navEntries.length > 7) {
$('#more-apps').show();
- $('#apps-management').hide();
+ $('.apps-management').hide();
} else {
$('#more-apps').hide();
- $('#apps-management').show();
+ $('.apps-management').show();
}
}
});
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index b47e2e28ffa..d94fbb33770 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -81,7 +81,7 @@
<input type="text" id="displayname" name="displayname"
<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
value="<?php p($_['displayName']) ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<?php if(!$_['displayNameChangeSupported']) { ?>
<span><?php if(isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
<?php } ?>
@@ -98,7 +98,7 @@
<input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
placeholder="<?php p($l->t('Your email address')); ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<?php if(!$_['displayNameChangeSupported']) { ?>
<span><?php if(isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
<?php } ?>
@@ -119,7 +119,7 @@
<input type="tel" id="phone" name="phone"
value="<?php p($_['phone']) ?>"
placeholder="<?php p($l->t('Your phone number')); ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<span class="icon-checkmark hidden"/>
<input type="hidden" id="phonescope" value="<?php p($_['phoneScope']) ?>">
</form>
@@ -133,7 +133,7 @@
<input type="text" id="address" name="address"
placeholder="<?php p($l->t('Your postal address')); ?>"
value="<?php p($_['address']) ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<span class="icon-checkmark hidden"/>
<input type="hidden" id="addressscope" value="<?php p($_['addressScope']) ?>">
</form>
@@ -146,7 +146,7 @@
</h2>
<input type="text" name="website" id="website" value="<?php p($_['website']); ?>"
placeholder="<?php p($l->t('Your website')); ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<span class="icon-checkmark hidden"/>
<input type="hidden" id="websitescope" value="<?php p($_['websiteScope']) ?>">
</form>
@@ -159,7 +159,7 @@
</h2>
<input type="text" name="twitter" id="twitter" value="<?php p($_['twitter']); ?>"
placeholder="<?php p($l->t('Your Twitter handle')); ?>"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
<span class="icon-checkmark hidden"/>
<input type="hidden" id="twitterscope" value="<?php p($_['twitterScope']) ?>">
</form>
@@ -188,13 +188,13 @@ if($_['passwordChangeSupported']) {
<label for="pass1" class="hidden-visually"><?php p($l->t('Current password')); ?>: </label>
<input type="password" id="pass1" name="oldpassword"
placeholder="<?php p($l->t('Current password'));?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" />
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
<div class="personal-show-container">
<label for="pass2" class="hidden-visually"><?php p($l->t('New password'));?>: </label>
<input type="password" id="pass2" name="newpassword"
placeholder="<?php p($l->t('New password')); ?>"
data-typetoggle="#personal-show"
- autocomplete="off" autocapitalize="off" autocorrect="off" />
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
<input type="checkbox" id="personal-show" name="show" /><label for="personal-show" class="personal-show-label"></label>
</div>
<input id="passwordbutton" type="submit" value="<?php p($l->t('Change password')); ?>" />
diff --git a/settings/templates/users/part.createuser.php b/settings/templates/users/part.createuser.php
index 6f23d06cfa3..ca36b196ea8 100644
--- a/settings/templates/users/part.createuser.php
+++ b/settings/templates/users/part.createuser.php
@@ -2,14 +2,14 @@
<form id="newuser" autocomplete="off">
<input id="newusername" type="text"
placeholder="<?php p($l->t('Username'))?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" />
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
<input
type="password" id="newuserpassword"
placeholder="<?php p($l->t('Password'))?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" />
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
<input id="newemail" type="text" style="display:none"
placeholder="<?php p($l->t('E-Mail'))?>"
- autocomplete="off" autocapitalize="off" autocorrect="off" />
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
<div class="groups"><div class="groupsListContainer multiselect button" data-placeholder="<?php p($l->t('Groups'))?>"><span class="title groupsList"></span><span class="icon-triangle-s"></span></div></div>
<input type="submit" class="button" value="<?php p($l->t('Create'))?>" />
</form>
diff --git a/tests/lib/App/ManagerTest.php b/tests/lib/App/ManagerTest.php
index e38f72b3d92..8b23168938c 100644
--- a/tests/lib/App/ManagerTest.php
+++ b/tests/lib/App/ManagerTest.php
@@ -116,16 +116,33 @@ class ManagerTest extends TestCase {
public function testEnableApp() {
$this->expectClearCache();
- $this->manager->enableApp('test');
- $this->assertEquals('yes', $this->appConfig->getValue('test', 'enabled', 'no'));
+ // making sure "files_trashbin" is disabled
+ if ($this->manager->isEnabledForUser('files_trashbin')) {
+ $this->manager->disableApp('files_trashbin');
+ }
+ $this->manager->enableApp('files_trashbin');
+ $this->assertEquals('yes', $this->appConfig->getValue('files_trashbin', 'enabled', 'no'));
}
public function testDisableApp() {
$this->expectClearCache();
- $this->manager->disableApp('test');
- $this->assertEquals('no', $this->appConfig->getValue('test', 'enabled', 'no'));
+ $this->manager->disableApp('files_trashbin');
+ $this->assertEquals('no', $this->appConfig->getValue('files_trashbin', 'enabled', 'no'));
}
+ public function testNotEnableIfNotInstalled() {
+ try {
+ $this->manager->enableApp('some_random_name_which_i_hope_is_not_an_app');
+ $this->assertFalse(true, 'If this line is reached the expected exception is not thrown.');
+ } catch (\Exception $e) {
+ // excpetion is expected
+ $this->assertEquals("some_random_name_which_i_hope_is_not_an_app can't be enabled since it is not installed.", $e->getMessage());
+ }
+ $this->assertEquals('no', $this->appConfig->getValue(
+ 'some_random_name_which_i_hope_is_not_an_app', 'enabled', 'no'
+ ));
+ }
+
public function testEnableAppForGroups() {
$groups = array(
new Group('group1', array(), null),
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index 0aaeb094cd4..3635323e169 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -1488,6 +1488,8 @@ class ViewTest extends \Test\TestCase {
/**
* @dataProvider pathRelativeToFilesProviderExceptionCases
* @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage $absolutePath must be relative to "files"
+ * @param string $path
*/
public function testGetPathRelativeToFilesWithInvalidArgument($path) {
$view = new View();
diff --git a/tests/lib/Group/ManagerTest.php b/tests/lib/Group/ManagerTest.php
index 1a7ced5f1ba..23a35024e0a 100644
--- a/tests/lib/Group/ManagerTest.php
+++ b/tests/lib/Group/ManagerTest.php
@@ -22,18 +22,24 @@
*/
namespace Test\Group;
+use OC\Group\Database;
use OC\User\Manager;
+use OCP\ILogger;
use OCP\IUser;
use OCP\GroupInterface;
+use Test\TestCase;
-class ManagerTest extends \Test\TestCase {
+class ManagerTest extends TestCase {
/** @var Manager|\PHPUnit_Framework_MockObject_MockObject $userManager */
protected $userManager;
+ /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject $userManager */
+ protected $logger;
protected function setUp() {
parent::setUp();
$this->userManager = $this->createMock(Manager::class);
+ $this->logger = $this->createMock(ILogger::class);
}
private function getTestUser($userId) {
@@ -47,8 +53,12 @@ class ManagerTest extends \Test\TestCase {
return $mockUser;
}
+ /**
+ * @param null|int $implementedActions
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
private function getTestBackend($implementedActions = null) {
- if (is_null($implementedActions)) {
+ if ($implementedActions === null) {
$implementedActions =
GroupInterface::ADD_TO_GROUP |
GroupInterface::REMOVE_FROM_GOUP |
@@ -58,7 +68,7 @@ class ManagerTest extends \Test\TestCase {
}
// need to declare it this way due to optional methods
// thanks to the implementsActions logic
- $backend = $this->getMockBuilder(\OCP\GroupInterface::class)
+ $backend = $this->getMockBuilder(GroupInterface::class)
->disableOriginalConstructor()
->setMethods([
'getGroupDetails',
@@ -91,7 +101,7 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$group = $manager->get('group1');
@@ -100,7 +110,7 @@ class ManagerTest extends \Test\TestCase {
}
public function testGetNoBackend() {
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$this->assertNull($manager->get('group1'));
}
@@ -115,7 +125,7 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(false));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$this->assertNull($manager->get('group1'));
@@ -125,7 +135,7 @@ class ManagerTest extends \Test\TestCase {
$backend = new \Test\Util\Group\Dummy();
$backend->createGroup('group1');
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$group = $manager->get('group1');
@@ -152,7 +162,7 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
@@ -162,9 +172,7 @@ class ManagerTest extends \Test\TestCase {
}
public function testCreate() {
- /**
- * @var \PHPUnit_Framework_MockObject_MockObject | \OC\Group\Backend $backend
- */
+ /**@var \PHPUnit_Framework_MockObject_MockObject|\OC\Group\Backend $backend */
$backendGroupCreated = false;
$backend = $this->getTestBackend();
$backend->expects($this->any())
@@ -177,9 +185,9 @@ class ManagerTest extends \Test\TestCase {
->method('createGroup')
->will($this->returnCallback(function () use (&$backendGroupCreated) {
$backendGroupCreated = true;
- }));;
+ }));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$group = $manager->createGroup('group1');
@@ -187,9 +195,7 @@ class ManagerTest extends \Test\TestCase {
}
public function testCreateExists() {
- /**
- * @var \PHPUnit_Framework_MockObject_MockObject | \OC\Group\Backend $backend
- */
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OC\Group\Backend $backend */
$backend = $this->getTestBackend();
$backend->expects($this->any())
->method('groupExists')
@@ -198,7 +204,7 @@ class ManagerTest extends \Test\TestCase {
$backend->expects($this->never())
->method('createGroup');
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$group = $manager->createGroup('group1');
@@ -219,11 +225,11 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$groups = $manager->search('1');
- $this->assertEquals(1, count($groups));
+ $this->assertCount(1, $groups);
$group1 = reset($groups);
$this->assertEquals('group1', $group1->getGID());
}
@@ -253,12 +259,12 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
$groups = $manager->search('1');
- $this->assertEquals(2, count($groups));
+ $this->assertCount(2, $groups);
$group1 = reset($groups);
$group12 = next($groups);
$this->assertEquals('group1', $group1->getGID());
@@ -290,18 +296,40 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
$groups = $manager->search('1', 2, 1);
- $this->assertEquals(2, count($groups));
+ $this->assertCount(2, $groups);
$group1 = reset($groups);
$group12 = next($groups);
$this->assertEquals('group1', $group1->getGID());
$this->assertEquals('group12', $group12->getGID());
}
+ public function testSearchResultExistsButGroupDoesNot() {
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OC\Group\Backend $backend */
+ $backend = $this->createMock(Database::class);
+ $backend->expects($this->once())
+ ->method('getGroups')
+ ->with('1')
+ ->will($this->returnValue(['group1']));
+ $backend->expects($this->once())
+ ->method('groupExists')
+ ->with('group1')
+ ->will($this->returnValue(false));
+
+ /** @var \OC\User\Manager $userManager */
+ $userManager = $this->createMock(Manager::class);
+
+ $manager = new \OC\Group\Manager($userManager, $this->logger);
+ $manager->addBackend($backend);
+
+ $groups = $manager->search('1');
+ $this->assertEmpty($groups);
+ }
+
public function testGetUserGroups() {
/**
* @var \PHPUnit_Framework_MockObject_MockObject | \OC\Group\Backend $backend
@@ -316,18 +344,18 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$groups = $manager->getUserGroups($this->getTestUser('user1'));
- $this->assertEquals(1, count($groups));
+ $this->assertCount(1, $groups);
$group1 = reset($groups);
$this->assertEquals('group1', $group1->getGID());
}
public function testGetUserGroupIds() {
/** @var \PHPUnit_Framework_MockObject_MockObject|\OC\Group\Manager $manager */
- $manager = $this->getMockBuilder('OC\Group\Manager')
+ $manager = $this->getMockBuilder(\OC\Group\Manager::class)
->disableOriginalConstructor()
->setMethods(['getUserGroups'])
->getMock();
@@ -338,19 +366,44 @@ class ManagerTest extends \Test\TestCase {
'abc' => 'abc',
]);
- /** @var \OC\User\User $user */
- $user = $this->getMockBuilder('OC\User\User')
- ->disableOriginalConstructor()
- ->getMock();
+ /** @var \OC\User\User|\PHPUnit_Framework_MockObject_MockObject $user */
+ $user = $this->createMock(IUser::class);
$groups = $manager->getUserGroupIds($user);
- $this->assertEquals(2, count($groups));
+ $this->assertCount(2, $groups);
foreach ($groups as $group) {
$this->assertInternalType('string', $group);
}
}
+ public function testGetUserGroupsWithDeletedGroup() {
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject | \OC\Group\Backend $backend
+ */
+ $backend = $this->createMock(Database::class);
+ $backend->expects($this->once())
+ ->method('getUserGroups')
+ ->with('user1')
+ ->will($this->returnValue(array('group1')));
+ $backend->expects($this->any())
+ ->method('groupExists')
+ ->with('group1')
+ ->will($this->returnValue(false));
+
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
+ $manager->addBackend($backend);
+
+ /** @var \OC\User\User|\PHPUnit_Framework_MockObject_MockObject $user */
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->atLeastOnce())
+ ->method('getUID')
+ ->willReturn('user1');
+
+ $groups = $manager->getUserGroups($user);
+ $this->assertEmpty($groups);
+ }
+
public function testInGroup() {
/**
* @var \PHPUnit_Framework_MockObject_MockObject | \OC\Group\Backend $backend
@@ -364,7 +417,7 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$this->assertTrue($manager->isInGroup('user1', 'group1'));
@@ -383,7 +436,7 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$this->assertTrue($manager->isAdmin('user1'));
@@ -402,7 +455,7 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$this->assertFalse($manager->isAdmin('user1'));
@@ -433,12 +486,12 @@ class ManagerTest extends \Test\TestCase {
->method('groupExists')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
$groups = $manager->getUserGroups($this->getTestUser('user1'));
- $this->assertEquals(2, count($groups));
+ $this->assertCount(2, $groups);
$group1 = reset($groups);
$group2 = next($groups);
$this->assertEquals('group1', $group1->getGID());
@@ -468,14 +521,10 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('searchDisplayName')
->with('user3')
- ->will($this->returnCallback(function($search, $limit, $offset) use ($userBackend) {
+ ->will($this->returnCallback(function($search, $limit, $offset) {
switch($offset) {
case 0 : return ['user3' => $this->getTestUser('user3'),
'user33' => $this->getTestUser('user33')];
@@ -485,7 +534,7 @@ class ManagerTest extends \Test\TestCase {
}));
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -496,11 +545,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3');
- $this->assertEquals(1, count($users));
+ $this->assertCount(1, $users);
$this->assertFalse(isset($users['user1']));
$this->assertFalse(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -531,14 +580,10 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('searchDisplayName')
->with('user3')
- ->will($this->returnCallback(function($search, $limit, $offset) use ($userBackend) {
+ ->will($this->returnCallback(function($search, $limit, $offset) {
switch($offset) {
case 0 : return ['user3' => $this->getTestUser('user3'),
'user33' => $this->getTestUser('user33')];
@@ -548,7 +593,7 @@ class ManagerTest extends \Test\TestCase {
}));
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -560,11 +605,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3', 1);
- $this->assertEquals(1, count($users));
+ $this->assertCount(1, $users);
$this->assertFalse(isset($users['user1']));
$this->assertFalse(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -596,14 +641,10 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('searchDisplayName')
->with('user3')
- ->will($this->returnCallback(function($search, $limit, $offset) use ($userBackend) {
+ ->will($this->returnCallback(function($search, $limit, $offset) {
switch($offset) {
case 0 :
return [
@@ -616,7 +657,7 @@ class ManagerTest extends \Test\TestCase {
}));
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -628,11 +669,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3', 1, 1);
- $this->assertEquals(1, count($users));
+ $this->assertCount(1, $users);
$this->assertFalse(isset($users['user1']));
$this->assertFalse(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -655,13 +696,9 @@ class ManagerTest extends \Test\TestCase {
->with('testgroup', '', -1, 0)
->will($this->returnValue(array('user2', 'user33')));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -672,11 +709,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '');
- $this->assertEquals(2, count($users));
+ $this->assertCount(2, $users);
$this->assertFalse(isset($users['user1']));
$this->assertTrue(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -698,13 +735,9 @@ class ManagerTest extends \Test\TestCase {
->with('testgroup', '', 1, 0)
->will($this->returnValue(array('user2')));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -715,11 +748,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '', 1);
- $this->assertEquals(1, count($users));
+ $this->assertCount(1, $users);
$this->assertFalse(isset($users['user1']));
$this->assertTrue(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -741,13 +774,9 @@ class ManagerTest extends \Test\TestCase {
->with('testgroup', '', 1, 1)
->will($this->returnValue(array('user33')));
- $userBackend = $this->getMockBuilder('\OC\User\Backend')
- ->disableOriginalConstructor()
- ->getMock();
-
$this->userManager->expects($this->any())
->method('get')
- ->will($this->returnCallback(function($uid) use ($userBackend) {
+ ->will($this->returnCallback(function($uid) {
switch($uid) {
case 'user1' : return $this->getTestUser('user1');
case 'user2' : return $this->getTestUser('user2');
@@ -758,11 +787,11 @@ class ManagerTest extends \Test\TestCase {
}
}));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '', 1, 1);
- $this->assertEquals(1, count($users));
+ $this->assertCount(1, $users);
$this->assertFalse(isset($users['user1']));
$this->assertFalse(isset($users['user2']));
$this->assertFalse(isset($users['user3']));
@@ -786,7 +815,7 @@ class ManagerTest extends \Test\TestCase {
->with('group1')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
// prime cache
@@ -797,11 +826,11 @@ class ManagerTest extends \Test\TestCase {
// add user
$group = $manager->get('group1');
$group->addUser($user1);
- $expectedGroups = ['group1'];
+ $expectedGroups[] = 'group1';
// check result
$groups = $manager->getUserGroups($user1);
- $this->assertEquals(1, count($groups));
+ $this->assertCount(1, $groups);
$group1 = reset($groups);
$this->assertEquals('group1', $group1->getGID());
}
@@ -829,13 +858,13 @@ class ManagerTest extends \Test\TestCase {
->method('removeFromGroup')
->will($this->returnValue(true));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
// prime cache
$user1 = $this->getTestUser('user1');
$groups = $manager->getUserGroups($user1);
- $this->assertEquals(1, count($groups));
+ $this->assertCount(1, $groups);
$group1 = reset($groups);
$this->assertEquals('group1', $group1->getGID());
@@ -859,7 +888,7 @@ class ManagerTest extends \Test\TestCase {
->with('user1')
->will($this->returnValue(null));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
$groups = $manager->getUserIdGroups('user1');
@@ -885,7 +914,7 @@ class ManagerTest extends \Test\TestCase {
['group2', ['gid' => 'group2']],
]));
- $manager = new \OC\Group\Manager($this->userManager);
+ $manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager->addBackend($backend);
// group with display name
diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php
index ddb24cdb3ee..50d46ae932d 100644
--- a/tests/lib/Preview/GeneratorTest.php
+++ b/tests/lib/Preview/GeneratorTest.php
@@ -399,6 +399,10 @@ class GeneratorTest extends \Test\TestCase {
);
$result = $this->generator->getPreview($file, $reqX, $reqY, $crop, $mode);
- $this->assertSame($preview, $result);
+ if ($expectedX === $maxX && $expectedY === $maxY) {
+ $this->assertSame($maxPreview, $result);
+ } else {
+ $this->assertSame($preview, $result);
+ }
}
}
diff --git a/tests/lib/Share20/DefaultShareProviderTest.php b/tests/lib/Share20/DefaultShareProviderTest.php
index 5870da8d218..a1e78313558 100644
--- a/tests/lib/Share20/DefaultShareProviderTest.php
+++ b/tests/lib/Share20/DefaultShareProviderTest.php
@@ -1524,6 +1524,48 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->provider->deleteFromSelf($share, 'user2');
}
+ /**
+ * @expectedException \OC\Share20\Exception\ProviderException
+ * @expectedExceptionMessage Group "group" does not exist
+ */
+ public function testDeleteFromSelfGroupDoesNotExist() {
+ $qb = $this->dbConn->getQueryBuilder();
+ $stmt = $qb->insert('share')
+ ->values([
+ 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
+ 'share_with' => $qb->expr()->literal('group'),
+ 'uid_owner' => $qb->expr()->literal('user1'),
+ 'uid_initiator' => $qb->expr()->literal('user1'),
+ 'item_type' => $qb->expr()->literal('file'),
+ 'file_source' => $qb->expr()->literal(1),
+ 'file_target' => $qb->expr()->literal('myTarget1'),
+ 'permissions' => $qb->expr()->literal(2)
+ ])->execute();
+ $this->assertEquals(1, $stmt);
+ $id = $qb->getLastInsertId();
+
+ $user1 = $this->getMock('\OCP\IUser');
+ $user1->method('getUID')->willReturn('user1');
+ $user2 = $this->getMock('\OCP\IUser');
+ $user2->method('getUID')->willReturn('user2');
+ $this->userManager->method('get')->will($this->returnValueMap([
+ ['user1', $user1],
+ ['user2', $user2],
+ ]));
+
+ $this->groupManager->method('get')->with('group')->willReturn(null);
+
+ $file = $this->getMock('\OCP\Files\File');
+ $file->method('getId')->willReturn(1);
+
+ $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
+ $this->rootFolder->method('getById')->with(1)->willReturn([$file]);
+
+ $share = $this->provider->getShareById($id);
+
+ $this->provider->deleteFromSelf($share, 'user2');
+ }
+
public function testDeleteFromSelfUser() {
$qb = $this->dbConn->getQueryBuilder();
$stmt = $qb->insert('share')
diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php
index 448373a8368..2a7df0df50f 100644
--- a/tests/lib/Share20/ManagerTest.php
+++ b/tests/lib/Share20/ManagerTest.php
@@ -1139,6 +1139,39 @@ class ManagerTest extends \Test\TestCase {
self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
}
+ public function testUserCreateChecksIdenticalPathSharedViaDeletedGroup() {
+ $share = $this->manager->newShare();
+
+ $sharedWith = $this->getMock('\OCP\IUser');
+ $sharedWith->method('getUID')->willReturn('sharedWith');
+
+ $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
+
+ $path = $this->getMock('\OCP\Files\Node');
+
+ $share->setSharedWith('sharedWith')
+ ->setNode($path)
+ ->setShareOwner('shareOwner')
+ ->setProviderId('foo')
+ ->setId('bar');
+
+ $share2 = $this->manager->newShare();
+ $share2->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+ ->setShareOwner('shareOwner2')
+ ->setProviderId('foo')
+ ->setId('baz')
+ ->setSharedWith('group');
+
+ $this->groupManager->method('get')->with('group')->willReturn(null);
+
+ $this->defaultProvider
+ ->method('getSharesByPath')
+ ->with($path)
+ ->willReturn([$share2]);
+
+ $this->assertNull($this->invokePrivate($this->manager, 'userCreateChecks', [$share]));
+ }
+
public function testUserCreateChecksIdenticalPathNotSharedWithUser() {
$share = $this->manager->newShare();
$sharedWith = $this->createMock(IUser::class);
@@ -1216,6 +1249,29 @@ class ManagerTest extends \Test\TestCase {
self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
}
+ /**
+ * @expectedException Exception
+ * @expectedExceptionMessage Only sharing within your own groups is allowed
+ */
+ public function testGroupCreateChecksShareWithGroupMembersOnlyNullGroup() {
+ $share = $this->manager->newShare();
+
+ $user = $this->getMock('\OCP\IUser');
+ $share->setSharedBy('user')->setSharedWith('group');
+
+ $this->groupManager->method('get')->with('group')->willReturn(null);
+ $this->userManager->method('get')->with('user')->willReturn($user);
+
+ $this->config
+ ->method('getAppValue')
+ ->will($this->returnValueMap([
+ ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
+ ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
+ ]));
+
+ $this->assertNull($this->invokePrivate($this->manager, 'groupCreateChecks', [$share]));
+ }
+
public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup() {
$share = $this->manager->newShare();
@@ -2666,6 +2722,23 @@ class ManagerTest extends \Test\TestCase {
$this->manager->moveShare($share, 'recipient');
}
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Group "shareWith" does not exist
+ */
+ public function testMoveShareGroupNull() {
+ $share = $this->manager->newShare();
+ $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP);
+ $share->setSharedWith('shareWith');
+
+ $recipient = $this->getMock('\OCP\IUser');
+
+ $this->groupManager->method('get')->with('shareWith')->willReturn(null);
+ $this->userManager->method('get')->with('recipient')->willReturn($recipient);
+
+ $this->manager->moveShare($share, 'recipient');
+ }
+
public function testMoveShareGroup() {
$share = $this->manager->newShare();
$share->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
diff --git a/tests/lib/SystemTag/SystemTagManagerTest.php b/tests/lib/SystemTag/SystemTagManagerTest.php
index e697e373465..61fac99ca6c 100644
--- a/tests/lib/SystemTag/SystemTagManagerTest.php
+++ b/tests/lib/SystemTag/SystemTagManagerTest.php
@@ -517,6 +517,15 @@ class SystemTagManagerTest extends TestCase {
}
/**
+ * empty groupIds should be ignored
+ */
+ public function testEmptyTagGroup() {
+ $tag1 = $this->tagManager->createTag('tag1', true, false);
+ $this->tagManager->setTagGroups($tag1, ['']);
+ $this->assertEquals([], $this->tagManager->getTagGroups($tag1));
+ }
+
+ /**
* @param ISystemTag $tag1
* @param ISystemTag $tag2
*/
diff --git a/tests/lib/User/DatabaseTest.php b/tests/lib/User/DatabaseTest.php
index d7e4b9256cb..0e6900651cd 100644
--- a/tests/lib/User/DatabaseTest.php
+++ b/tests/lib/User/DatabaseTest.php
@@ -87,7 +87,7 @@ class DatabaseTest extends Backend {
$this->eventDispatcher->expects($this->once())->method('dispatch')
->willReturnCallback(
function ($eventName, GenericEvent $event) {
- $this->assertSame('OCP\PasswordPolicy::validate', $eventName);
+ $this->assertSame('OCP\PasswordPolicy::validate', $eventName);
$this->assertSame('newpass', $event->getSubject());
throw new HintException('password change failed', 'password change failed');
}
@@ -96,4 +96,21 @@ class DatabaseTest extends Backend {
$this->backend->setPassword($user, 'newpass');
$this->assertSame($user, $this->backend->checkPassword($user, 'newpass'));
}
+
+ public function testCreateUserInvalidatesCache() {
+ $user1 = $this->getUniqueID('test_');
+ $this->assertFalse($this->backend->userExists($user1));
+ $this->backend->createUser($user1, 'pw');
+ $this->assertTrue($this->backend->userExists($user1));
+ }
+
+ public function testDeleteUserInvalidatesCache() {
+ $user1 = $this->getUniqueID('test_');
+ $this->backend->createUser($user1, 'pw');
+ $this->assertTrue($this->backend->userExists($user1));
+ $this->backend->deleteUser($user1);
+ $this->assertFalse($this->backend->userExists($user1));
+ $this->backend->createUser($user1, 'pw2');
+ $this->assertTrue($this->backend->userExists($user1));
+ }
}