diff options
19 files changed, 154 insertions, 43 deletions
diff --git a/apps/contactsinteraction/lib/Db/RecentContact.php b/apps/contactsinteraction/lib/Db/RecentContact.php index 475de093419..e6c379d0aa1 100644 --- a/apps/contactsinteraction/lib/Db/RecentContact.php +++ b/apps/contactsinteraction/lib/Db/RecentContact.php @@ -66,7 +66,7 @@ class RecentContact extends Entity { $this->addType('uid', 'string'); $this->addType('email', 'string'); $this->addType('federatedCloudId', 'string'); - $this->addType('card', 'string'); + $this->addType('card', 'blob'); $this->addType('lastContact', 'int'); } } diff --git a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php index 69b2dd5877e..db79ea21b0e 100644 --- a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php @@ -32,6 +32,7 @@ use OC\Files\FileInfo; use OC\Files\Storage\Wrapper\Quota; use OCA\DAV\Connector\Sabre\Directory; use OCP\Files\ForbiddenException; +use OCP\Files\Mount\IMountPoint; class TestViewDirectory extends \OC\Files\View { private $updatables; @@ -269,9 +270,12 @@ class DirectoryTest extends \Test\TestCase { } public function testGetQuotaInfoUnlimited() { + $mountPoint = $this->createMock(IMountPoint::class); $storage = $this->getMockBuilder(Quota::class) ->disableOriginalConstructor() ->getMock(); + $mountPoint->method('getStorage') + ->willReturn($storage); $storage->expects($this->any()) ->method('instanceOfStorage') @@ -292,8 +296,8 @@ class DirectoryTest extends \Test\TestCase { ->willReturn(200); $this->info->expects($this->once()) - ->method('getStorage') - ->willReturn($storage); + ->method('getMountPoint') + ->willReturn($mountPoint); $this->view->expects($this->once()) ->method('getFileInfo') @@ -304,9 +308,12 @@ class DirectoryTest extends \Test\TestCase { } public function testGetQuotaInfoSpecific() { + $mountPoint = $this->createMock(IMountPoint::class); $storage = $this->getMockBuilder(Quota::class) ->disableOriginalConstructor() ->getMock(); + $mountPoint->method('getStorage') + ->willReturn($storage); $storage->expects($this->any()) ->method('instanceOfStorage') @@ -328,8 +335,8 @@ class DirectoryTest extends \Test\TestCase { ->willReturn(200); $this->info->expects($this->once()) - ->method('getStorage') - ->willReturn($storage); + ->method('getMountPoint') + ->willReturn($mountPoint); $this->view->expects($this->once()) ->method('getFileInfo') diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 28e4c5f575a..cdc1c70ffc5 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -72,6 +72,7 @@ $('#free_space').val(response.data.freeSpace); $('#upload.button').attr('data-original-title', response.data.maxHumanFilesize); $('#usedSpacePercent').val(response.data.usedSpacePercent); + $('#usedSpacePercent').data('mount-type', response.data.mountType); $('#owner').val(response.data.owner); $('#ownerDisplayName').val(response.data.ownerDisplayName); Files.displayStorageWarnings(); @@ -155,21 +156,30 @@ var usedSpacePercent = $('#usedSpacePercent').val(), owner = $('#owner').val(), - ownerDisplayName = $('#ownerDisplayName').val(); + ownerDisplayName = $('#ownerDisplayName').val(), + mountType = $('#usedSpacePercent').data('mount-type'); if (usedSpacePercent > 98) { if (owner !== OC.getCurrentUser().uid) { OC.Notification.show(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!', {owner: ownerDisplayName}), {type: 'error'} ); - return; + } else if (mountType === 'group') { + OC.Notification.show(t('files', + 'This group folder is full, files can not be updated or synced anymore!'), + {type: 'error'} + ); + } else if (mountType === 'external') { + OC.Notification.show(t('files', + 'This external storage is full, files can not be updated or synced anymore!'), + {type : 'error'} + ); + } else { + OC.Notification.show(t('files', + 'Your storage is full, files can not be updated or synced anymore!'), + {type: 'error'} + ); } - OC.Notification.show(t('files', - 'Your storage is full, files can not be updated or synced anymore!'), - {type : 'error'} - ); - return; - } - if (usedSpacePercent > 90) { + } else if (usedSpacePercent > 90) { if (owner !== OC.getCurrentUser().uid) { OC.Notification.show(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)', { @@ -180,12 +190,24 @@ type: 'error' } ); - return; + } else if (mountType === 'group') { + OC.Notification.show(t('files', + 'This group folder is almost full ({usedSpacePercent}%)', + {usedSpacePercent: usedSpacePercent}), + {type : 'error'} + ); + } else if (mountType === 'external') { + OC.Notification.show(t('files', + 'This external storage is almost full ({usedSpacePercent}%)', + {usedSpacePercent: usedSpacePercent}), + {type : 'error'} + ); + } else { + OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', + {usedSpacePercent: usedSpacePercent}), + {type : 'error'} + ); } - OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', - {usedSpacePercent: usedSpacePercent}), - {type : 'error'} - ); } }, diff --git a/apps/files/lib/Helper.php b/apps/files/lib/Helper.php index 3431fb2ffc7..1f728565ca6 100644 --- a/apps/files/lib/Helper.php +++ b/apps/files/lib/Helper.php @@ -63,6 +63,7 @@ class Helper { 'usedSpacePercent' => (int)$storageInfo['relative'], 'owner' => $storageInfo['owner'], 'ownerDisplayName' => $storageInfo['ownerDisplayName'], + 'mountType' => $storageInfo['mountType'], ]; } diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index e6cd5a9eeb9..f38f175dd66 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -9,6 +9,6 @@ }, "require": { "icewind/streams": "0.7.1", - "icewind/smb": "3.2.6" + "icewind/smb": "3.2.7" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 1ece93dccfc..de8642d82fb 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3b3638566fc1597d1a48c43e2a0da72a", + "content-hash": "6181c23a5c03b00fbdc659d87c1ad67d", "packages": [ { "name": "icewind/smb", - "version": "v3.2.6", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "507b186800ac6c3b287604a4ff9b138cf430da79" + "reference": "743a7bf35317f1b76cf8e8b804e54a6c5faacad6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/507b186800ac6c3b287604a4ff9b138cf430da79", - "reference": "507b186800ac6c3b287604a4ff9b138cf430da79", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/743a7bf35317f1b76cf8e8b804e54a6c5faacad6", + "reference": "743a7bf35317f1b76cf8e8b804e54a6c5faacad6", "shasum": "" }, "require": { @@ -45,7 +45,7 @@ } ], "description": "php wrapper for smbclient and libsmbclient-php", - "time": "2020-07-20T14:12:51+00:00" + "time": "2020-09-03T13:00:22+00:00" }, { "name": "icewind/streams", diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index b96750e1635..d903f99b5d9 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -1,17 +1,17 @@ [ { "name": "icewind/smb", - "version": "v3.2.6", - "version_normalized": "3.2.6.0", + "version": "v3.2.7", + "version_normalized": "3.2.7.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "507b186800ac6c3b287604a4ff9b138cf430da79" + "reference": "743a7bf35317f1b76cf8e8b804e54a6c5faacad6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/507b186800ac6c3b287604a4ff9b138cf430da79", - "reference": "507b186800ac6c3b287604a4ff9b138cf430da79", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/743a7bf35317f1b76cf8e8b804e54a6c5faacad6", + "reference": "743a7bf35317f1b76cf8e8b804e54a6c5faacad6", "shasum": "" }, "require": { @@ -22,7 +22,7 @@ "friendsofphp/php-cs-fixer": "^2.13", "phpunit/phpunit": "^7.0" }, - "time": "2020-07-20T14:12:51+00:00", + "time": "2020-09-03T13:00:22+00:00", "type": "library", "installation-source": "dist", "autoload": { diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php index 6a0270ef8f4..d8be57c7311 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php @@ -113,7 +113,7 @@ class NativeFileInfo implements IFileInfo { // Let us ignore the ATTR_NOT_CONTENT_INDEXED for now $mode &= ~0x00002000; - return $this->stat()['mode']; + return $mode; } /** diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index db6fa35e85c..d6c0644ccef 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -708,11 +708,13 @@ class Trashbin { */ private static function calculateFreeSpace($trashbinSize, $user) { $config = \OC::$server->getConfig(); - $systemTrashbinSize = (int)$config->getAppValue('files_trashbin', 'trashbin_size', '-1'); $userTrashbinSize = (int)$config->getUserValue($user, 'files_trashbin', 'trashbin_size', '-1'); - $configuredTrashbinSize = ($userTrashbinSize < 0) ? $systemTrashbinSize : $userTrashbinSize; - if ($configuredTrashbinSize) { - return $configuredTrashbinSize - $trashbinSize; + if ($userTrashbinSize > -1) { + return $userTrashbinSize - $trashbinSize; + } + $systemTrashbinSize = (int)$config->getAppValue('files_trashbin', 'trashbin_size', '-1'); + if ($systemTrashbinSize > -1) { + return $systemTrashbinSize - $trashbinSize; } $softQuota = true; diff --git a/apps/files_trashbin/tests/TrashbinTest.php b/apps/files_trashbin/tests/TrashbinTest.php index 136d8121cfa..40c3256ee03 100644 --- a/apps/files_trashbin/tests/TrashbinTest.php +++ b/apps/files_trashbin/tests/TrashbinTest.php @@ -119,15 +119,25 @@ class TrashbinTest extends \Test\TestCase { \OC::$server->getAppManager()->enableApp('files_trashbin'); $config = \OC::$server->getConfig(); $mockConfig = $this->createMock(\OCP\IConfig::class); - $mockConfig->expects($this->any()) + $mockConfig ->method('getSystemValue') - ->willReturnCallback(function ($key, $default) use ($config) { + ->willReturnCallback(static function ($key, $default) use ($config) { if ($key === 'filesystem_check_changes') { return \OC\Files\Cache\Watcher::CHECK_ONCE; } else { return $config->getSystemValue($key, $default); } }); + $mockConfig + ->method('getUserValue') + ->willReturnCallback(static function ($userId, $appName, $key, $default = '') use ($config) { + return $config->getUserValue($userId, $appName, $key, $default); + }); + $mockConfig + ->method('getAppValue') + ->willReturnCallback(static function ($appName, $key, $default = '') use ($config) { + return $config->getAppValue($appName, $key, $default); + }); $this->overwriteService(\OC\AllConfig::class, $mockConfig); $this->trashRoot1 = '/' . self::TEST_TRASHBIN_USER1 . '/files_trashbin'; diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 62b137523cf..81fc7601c78 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -613,6 +613,7 @@ return array( 'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php', 'OC\\Authentication\\Listeners\\UserDeletedStoreCleanupListener' => $baseDir . '/lib/private/Authentication/Listeners/UserDeletedStoreCleanupListener.php', 'OC\\Authentication\\Listeners\\UserDeletedTokenCleanupListener' => $baseDir . '/lib/private/Authentication/Listeners/UserDeletedTokenCleanupListener.php', + 'OC\\Authentication\\Listeners\\UserLoggedInListener' => $baseDir . '/lib/private/Authentication/Listeners/UserLoggedInListener.php', 'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => $baseDir . '/lib/private/Authentication/Login/ALoginCommand.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 285a834e5ca..02b476d57ba 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -642,6 +642,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php', 'OC\\Authentication\\Listeners\\UserDeletedStoreCleanupListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserDeletedStoreCleanupListener.php', 'OC\\Authentication\\Listeners\\UserDeletedTokenCleanupListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserDeletedTokenCleanupListener.php', + 'OC\\Authentication\\Listeners\\UserLoggedInListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserLoggedInListener.php', 'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/ALoginCommand.php', diff --git a/lib/private/Authentication/Listeners/UserLoggedInListener.php b/lib/private/Authentication/Listeners/UserLoggedInListener.php new file mode 100644 index 00000000000..0347b4f5d1f --- /dev/null +++ b/lib/private/Authentication/Listeners/UserLoggedInListener.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Authentication\Listeners; + +use OC\Authentication\Token\Manager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\User\Events\PostLoginEvent; + +class UserLoggedInListener implements IEventListener { + + /** @var Manager */ + private $manager; + + public function __construct(Manager $manager) { + $this->manager = $manager; + } + + public function handle(Event $event): void { + if (!($event instanceof PostLoginEvent)) { + return; + } + + // If this is already a token login there is nothing to do + if ($event->isTokenLogin()) { + return; + } + + $this->manager->updatePasswords($event->getUser()->getUID(), $event->getPassword()); + } +} diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index 664440fe6bb..17d6a351c8e 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -419,6 +419,7 @@ class PublicKeyTokenProvider implements IProvider { foreach ($tokens as $t) { $publicKey = $t->getPublicKey(); $t->setPassword($this->encryptPassword($password, $publicKey)); + $t->setPasswordInvalid(false); $this->updateToken($t); } } diff --git a/lib/private/Server.php b/lib/private/Server.php index da92c647a1d..b1227663c5b 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -65,6 +65,7 @@ use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\TimeFactory; use OC\Authentication\Events\LoginFailed; use OC\Authentication\Listeners\LoginFailedListener; +use OC\Authentication\Listeners\UserLoggedInListener; use OC\Authentication\LoginCredentials\Store; use OC\Authentication\Token\IProvider; use OC\Avatar\AvatarManager; @@ -221,6 +222,7 @@ use OCP\User\Events\BeforeUserLoggedInEvent; use OCP\User\Events\BeforeUserLoggedInWithCookieEvent; use OCP\User\Events\BeforeUserLoggedOutEvent; use OCP\User\Events\PasswordUpdatedEvent; +use OCP\User\Events\PostLoginEvent; use OCP\User\Events\UserChangedEvent; use OCP\User\Events\UserCreatedEvent; use OCP\User\Events\UserDeletedEvent; @@ -1429,6 +1431,7 @@ class Server extends ServerContainer implements IServerContainer { /** @var IEventDispatcher $eventDispatched */ $eventDispatched = $this->query(IEventDispatcher::class); $eventDispatched->addServiceListener(LoginFailed::class, LoginFailedListener::class); + $eventDispatched->addServiceListener(PostLoginEvent::class, UserLoggedInListener::class); } /** diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php index 750d33fd726..b5c16d1690b 100644 --- a/lib/private/Template/CSSResourceLocator.php +++ b/lib/private/Template/CSSResourceLocator.php @@ -109,7 +109,7 @@ class CSSResourceLocator extends ResourceLocator { if (is_file($root.'/'.$file)) { if ($this->scssCacher !== null) { if ($this->scssCacher->process($root, $file, $app)) { - $this->append($root, $this->scssCacher->getCachedSCSS($app, $file), \OC::$WEBROOT, true, true); + $this->append($this->serverroot, $this->scssCacher->getCachedSCSS($app, $file), \OC::$WEBROOT, true, true); return true; } else { $this->logger->warning('Failed to compile and/or save '.$root.'/'.$file, ['app' => 'core']); @@ -145,7 +145,7 @@ class CSSResourceLocator extends ResourceLocator { } } - $this->resources[] = [$webRoot? : \OC::$WEBROOT, $webRoot, $file]; + $this->resources[] = [$webRoot ?: \OC::$WEBROOT, $webRoot, $file]; } } } diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php index 8cd492de117..d9c0c16de0d 100644 --- a/lib/private/legacy/OC_Helper.php +++ b/lib/private/legacy/OC_Helper.php @@ -495,7 +495,8 @@ class OC_Helper { $used = 0; } $quota = \OCP\Files\FileInfo::SPACE_UNLIMITED; - $storage = $rootInfo->getStorage(); + $mount = $rootInfo->getMountPoint(); + $storage = $mount->getStorage(); $sourceStorage = $storage; if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) { $includeExtStorage = false; @@ -553,6 +554,7 @@ class OC_Helper { 'relative' => $relative, 'owner' => $ownerId, 'ownerDisplayName' => $ownerDisplayName, + 'mountType' => $mount->getMountType() ]; } diff --git a/lib/public/AppFramework/Db/Entity.php b/lib/public/AppFramework/Db/Entity.php index 954b8787c4c..34719c82aea 100644 --- a/lib/public/AppFramework/Db/Entity.php +++ b/lib/public/AppFramework/Db/Entity.php @@ -110,7 +110,12 @@ abstract class Entity { // if type definition exists, cast to correct type if ($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) { - settype($args[0], $this->_fieldTypes[$name]); + $type = $this->_fieldTypes[$name]; + if ($type === 'blob') { + // (B)LOB is treated as string when we read from the DB + $type = 'string'; + } + settype($args[0], $type); } $this->$name = $args[0]; } else { diff --git a/lib/public/AppFramework/Db/QBMapper.php b/lib/public/AppFramework/Db/QBMapper.php index 9b396965706..ebbe92e7875 100644 --- a/lib/public/AppFramework/Db/QBMapper.php +++ b/lib/public/AppFramework/Db/QBMapper.php @@ -230,6 +230,8 @@ abstract class QBMapper { case 'bool': case 'boolean': return IQueryBuilder::PARAM_BOOL; + case 'blob': + return IQueryBuilder::PARAM_LOB; } return IQueryBuilder::PARAM_STR; |