diff options
-rw-r--r-- | apps/dav/appinfo/info.xml | 4 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/Converter.php | 2 | ||||
-rw-r--r-- | apps/dav/lib/Migration/Classification.php | 94 | ||||
-rw-r--r-- | apps/dav/lib/Migration/GenerateBirthdays.php | 71 | ||||
-rw-r--r-- | apps/dav/tests/unit/CardDAV/ConverterTest.php | 46 | ||||
-rw-r--r-- | apps/dav/tests/unit/Migration/ClassificationTest.php | 65 | ||||
-rw-r--r-- | apps/encryption/lib/Crypto/Encryption.php | 8 | ||||
-rw-r--r-- | apps/encryption/lib/Session.php | 10 | ||||
-rw-r--r-- | apps/encryption/tests/Crypto/EncryptionTest.php | 15 | ||||
-rw-r--r-- | apps/encryption/tests/SessionTest.php | 26 | ||||
-rw-r--r-- | apps/files/css/files.css | 12 | ||||
-rw-r--r-- | apps/files_sharing/lib/Activity/Providers/Downloads.php | 12 | ||||
-rw-r--r-- | apps/files_sharing/lib/Activity/Providers/RemoteShares.php | 5 | ||||
-rw-r--r-- | apps/theming/lib/Controller/ThemingController.php | 4 | ||||
-rw-r--r-- | core/js/sharedialogview.js | 12 | ||||
-rw-r--r-- | lib/base.php | 10 | ||||
-rw-r--r-- | lib/private/AppFramework/Http/Request.php | 33 | ||||
-rw-r--r-- | settings/Application.php | 136 | ||||
-rw-r--r-- | tests/lib/AppFramework/Http/RequestTest.php | 70 |
19 files changed, 237 insertions, 398 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 314391a1448..0024e41e753 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -22,12 +22,8 @@ </background-jobs> <repair-steps> <post-migration> - <step>OCA\DAV\Migration\Classification</step> <step>OCA\DAV\Migration\FixBirthdayCalendarComponent</step> </post-migration> - <live-migration> - <step>OCA\DAV\Migration\GenerateBirthdays</step> - </live-migration> </repair-steps> <commands> <command>OCA\DAV\Command\CreateAddressBook</command> diff --git a/apps/dav/lib/CardDAV/Converter.php b/apps/dav/lib/CardDAV/Converter.php index 065c5494ec3..ba0c4c2a2d5 100644 --- a/apps/dav/lib/CardDAV/Converter.php +++ b/apps/dav/lib/CardDAV/Converter.php @@ -71,7 +71,7 @@ class Converter { break; case AccountManager::PROPERTY_AVATAR: if ($image !== null) { - $vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]); + $vCard->add('PHOTO', 'data:'.$image->mimeType().';base64,' . base64_encode($image->data())); } break; case AccountManager::PROPERTY_EMAIL: diff --git a/apps/dav/lib/Migration/Classification.php b/apps/dav/lib/Migration/Classification.php deleted file mode 100644 index a18646023c8..00000000000 --- a/apps/dav/lib/Migration/Classification.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OCA\DAV\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCP\IUser; -use OCP\IUserManager; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class Classification implements IRepairStep { - - /** @var CalDavBackend */ - private $calDavBackend; - - /** @var IUserManager */ - private $userManager; - - /** - * Classification constructor. - * - * @param CalDavBackend $calDavBackend - */ - public function __construct(CalDavBackend $calDavBackend, IUserManager $userManager) { - $this->calDavBackend = $calDavBackend; - $this->userManager = $userManager; - } - - /** - * @param IUser $user - */ - public function runForUser($user) { - $principal = 'principals/users/' . $user->getUID(); - $calendars = $this->calDavBackend->getCalendarsForUser($principal); - foreach ($calendars as $calendar) { - $objects = $this->calDavBackend->getCalendarObjects($calendar['id']); - foreach ($objects as $object) { - $calObject = $this->calDavBackend->getCalendarObject($calendar['id'], $object['uri']); - $classification = $this->extractClassification($calObject['calendardata']); - $this->calDavBackend->setClassification($object['id'], $classification); - } - } - } - - /** - * @param $calendarData - * @return integer - * @throws \Sabre\DAV\Exception\BadRequest - */ - protected function extractClassification($calendarData) { - return $this->calDavBackend->getDenormalizedData($calendarData)['classification']; - } - - /** - * @inheritdoc - */ - public function getName() { - return 'Fix classification for calendar objects'; - } - - /** - * @inheritdoc - */ - public function run(IOutput $output) { - $output->startProgress(); - $this->userManager->callForAllUsers(function($user) use ($output) { - /** @var IUser $user */ - $output->advance(1, $user->getDisplayName()); - $this->runForUser($user); - }); - $output->finishProgress(); - } -} diff --git a/apps/dav/lib/Migration/GenerateBirthdays.php b/apps/dav/lib/Migration/GenerateBirthdays.php deleted file mode 100644 index 20e000314ac..00000000000 --- a/apps/dav/lib/Migration/GenerateBirthdays.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OCA\DAV\Migration; - -use OCA\DAV\CalDAV\BirthdayService; -use OCP\IUser; -use OCP\IUserManager; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class GenerateBirthdays implements IRepairStep { - - /** @var BirthdayService */ - private $birthdayService; - - /** @var IUserManager */ - private $userManager; - - /** - * GenerateBirthdays constructor. - * - * @param BirthdayService $birthdayService - * @param IUserManager $userManager - */ - public function __construct(BirthdayService $birthdayService, IUserManager $userManager) { - $this->birthdayService = $birthdayService; - $this->userManager = $userManager; - } - - /** - * @inheritdoc - */ - public function getName() { - return 'Regenerate birthday calendar for all users'; - } - - /** - * @inheritdoc - */ - public function run(IOutput $output) { - - $output->startProgress(); - $this->userManager->callForAllUsers(function($user) use ($output) { - /** @var IUser $user */ - $output->advance(1, $user->getDisplayName()); - $this->birthdayService->syncUser($user->getUID()); - }); - $output->finishProgress(); - } -} diff --git a/apps/dav/tests/unit/CardDAV/ConverterTest.php b/apps/dav/tests/unit/CardDAV/ConverterTest.php index 737bbd96aaa..528b3aa9ef4 100644 --- a/apps/dav/tests/unit/CardDAV/ConverterTest.php +++ b/apps/dav/tests/unit/CardDAV/ConverterTest.php @@ -134,11 +134,45 @@ class ConverterTest extends TestCase { public function providesNewUsers() { return [ - [null], - [null, null, 'foo@bar.net'], - [['cloud' => 'foo@cloud.net', 'email' => 'foo@bar.net'], null, 'foo@bar.net', 'foo@cloud.net'], - [['cloud' => 'foo@cloud.net', 'email' => 'foo@bar.net', 'fn' => 'Dr. Foo Bar'], "Dr. Foo Bar", "foo@bar.net", 'foo@cloud.net'], - [['cloud' => 'foo@cloud.net', 'fn' => 'Dr. Foo Bar'], "Dr. Foo Bar", null, "foo@cloud.net"], + [ + null + ], + [ + null, + null, + 'foo@bar.net' + ], + [ + [ + 'cloud' => 'foo@cloud.net', + 'email' => 'foo@bar.net', + 'photo' => 'data:image/jpeg;base64,MTIzNDU2Nzg5', + ], + null, + 'foo@bar.net', + 'foo@cloud.net' + ], + [ + [ + 'cloud' => 'foo@cloud.net', + 'email' => 'foo@bar.net', + 'fn' => 'Dr. Foo Bar', + 'photo' => 'data:image/jpeg;base64,MTIzNDU2Nzg5', + ], + "Dr. Foo Bar", + "foo@bar.net", + 'foo@cloud.net' + ], + [ + [ + 'cloud' => 'foo@cloud.net', + 'fn' => 'Dr. Foo Bar', + 'photo' => 'data:image/jpeg;base64,MTIzNDU2Nzg5', + ], + "Dr. Foo Bar", + null, + "foo@cloud.net" + ], ]; } @@ -171,7 +205,7 @@ class ConverterTest extends TestCase { */ protected function getUserMock($displayName, $eMailAddress, $cloudId) { $image0 = $this->getMockBuilder(IImage::class)->disableOriginalConstructor()->getMock(); - $image0->method('mimeType')->willReturn('JPEG'); + $image0->method('mimeType')->willReturn('image/jpeg'); $image0->method('data')->willReturn('123456789'); $user = $this->getMockBuilder(IUser::class)->disableOriginalConstructor()->getMock(); $user->method('getUID')->willReturn('12345'); diff --git a/apps/dav/tests/unit/Migration/ClassificationTest.php b/apps/dav/tests/unit/Migration/ClassificationTest.php deleted file mode 100644 index 1960fa031e1..00000000000 --- a/apps/dav/tests/unit/Migration/ClassificationTest.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\DAV\Tests\unit\DAV\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCA\DAV\Migration\Classification; -use OCA\DAV\Tests\unit\CalDAV\AbstractCalDavBackendTest; -use OCP\IUser; - -/** - * Class ClassificationTest - * - * @group DB - * - * @package OCA\DAV\Tests\unit\DAV - */ -class ClassificationTest extends AbstractCalDavBackendTest { - public function test() { - // setup data - $calendarId = $this->createTestCalendar(); - $eventUri = $this->createEvent($calendarId, '20130912T130000Z', '20130912T140000Z'); - $object = $this->backend->getCalendarObject($calendarId, $eventUri); - - // assert proper classification - $this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']); - $this->backend->setClassification($object['id'], CalDavBackend::CLASSIFICATION_CONFIDENTIAL); - $object = $this->backend->getCalendarObject($calendarId, $eventUri); - $this->assertEquals(CalDavBackend::CLASSIFICATION_CONFIDENTIAL, $object['classification']); - - // run migration - $c = new Classification($this->backend, $this->userManager); - - /** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ - $user = $this->getMockBuilder('OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $user->expects($this->once())->method('getUID')->willReturn('caldav-unit-test'); - - $c->runForUser($user); - - // assert classification after migration - $object = $this->backend->getCalendarObject($calendarId, $eventUri); - $this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']); - } -} diff --git a/apps/encryption/lib/Crypto/Encryption.php b/apps/encryption/lib/Crypto/Encryption.php index c71e25b6442..fdcbd41a09c 100644 --- a/apps/encryption/lib/Crypto/Encryption.php +++ b/apps/encryption/lib/Crypto/Encryption.php @@ -177,6 +177,14 @@ class Encryption implements IEncryptionModule { $this->isWriteOperation = false; $this->writeCache = ''; + if($this->session->isReady() === false) { + // if the master key is enabled we can initialize encryption + // with a empty password and user name + if ($this->util->isMasterKeyEnabled()) { + $this->keyManager->init('', ''); + } + } + if ($this->session->decryptAllModeActivated()) { $encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path); $shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid()); diff --git a/apps/encryption/lib/Session.php b/apps/encryption/lib/Session.php index 92132d6080c..a61ee25fadb 100644 --- a/apps/encryption/lib/Session.php +++ b/apps/encryption/lib/Session.php @@ -68,6 +68,16 @@ class Session { } /** + * check if encryption was initialized successfully + * + * @return bool + */ + public function isReady() { + $status = $this->getStatus(); + return $status === self::INIT_SUCCESSFUL; + } + + /** * Gets user or public share private key from session * * @return string $privateKey The user's plaintext private key diff --git a/apps/encryption/tests/Crypto/EncryptionTest.php b/apps/encryption/tests/Crypto/EncryptionTest.php index 658f6275bb4..3525d2d4aec 100644 --- a/apps/encryption/tests/Crypto/EncryptionTest.php +++ b/apps/encryption/tests/Crypto/EncryptionTest.php @@ -280,6 +280,21 @@ class EncryptionTest extends TestCase { } /** + * test begin() if encryption is not initialized but the master key is enabled + * in this case we can initialize the encryption without a username/password + * and continue + */ + public function testBeginInitMasterKey() { + + $this->sessionMock->expects($this->once())->method('isReady')->willReturn(false); + $this->utilMock->expects($this->once())->method('isMasterKeyEnabled') + ->willReturn(true); + $this->keyManagerMock->expects($this->once())->method('init')->with('', ''); + + $this->instance->begin('/user/files/welcome.txt', 'user', 'r', [], []); + } + + /** * @dataProvider dataTestUpdate * * @param string $fileKey diff --git a/apps/encryption/tests/SessionTest.php b/apps/encryption/tests/SessionTest.php index 099acddbca1..3000fedf2c3 100644 --- a/apps/encryption/tests/SessionTest.php +++ b/apps/encryption/tests/SessionTest.php @@ -134,6 +134,32 @@ class SessionTest extends TestCase { } /** + * @dataProvider dataTestIsReady + * + * @param int $status + * @param bool $expected + */ + public function testIsReady($status, $expected) { + /** @var Session | \PHPUnit_Framework_MockObject_MockObject $instance */ + $instance = $this->getMockBuilder(Session::class) + ->setConstructorArgs([$this->sessionMock]) + ->setMethods(['getStatus'])->getMock(); + + $instance->expects($this->once())->method('getStatus') + ->willReturn($status); + + $this->assertSame($expected, $instance->isReady()); + } + + public function dataTestIsReady() { + return [ + [Session::INIT_SUCCESSFUL, true], + [Session::INIT_EXECUTED, false], + [Session::NOT_INITIALIZED, false], + ]; + } + + /** * @param $key * @param $value */ diff --git a/apps/files/css/files.css b/apps/files/css/files.css index c0460ff6058..1983d51809c 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -652,7 +652,7 @@ html.ie8 .column-mtime .selectedActions { #fileList .name:focus a.action:focus { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter: alpha(opacity=70); - opacity: 7; + opacity: .7; display:inline; } #fileList tr a.action.disabled { @@ -660,14 +660,20 @@ html.ie8 .column-mtime .selectedActions { } /* show share action of shared items darker to distinguish from non-shared */ -#fileList a.action.permanent.shared-style, -#fileList a.action.action-favorite.permanent { +#fileList a.action.action-share.permanent.shared-style, +#fileList a.action.action-favorite.permanent, +/* show hovered permanent entries darker */ +#fileList tr a.action.action-share.permanent:hover, +#fileList tr a.action.action-share.permanent:focus, +#fileList tr a.action.action-menu.permanent:hover, +#fileList tr a.action.action-menu.permanent:focus { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)" !important; filter: alpha(opacity=70) !important; opacity: .7 !important; display:inline; } /* always show actions on mobile, not only on hover */ +#fileList a.action.action-share.permanent, #fileList a.action.action-menu.permanent { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)" !important; filter: alpha(opacity=30) !important; diff --git a/apps/files_sharing/lib/Activity/Providers/Downloads.php b/apps/files_sharing/lib/Activity/Providers/Downloads.php index 84ef5895dde..39e2a846b30 100644 --- a/apps/files_sharing/lib/Activity/Providers/Downloads.php +++ b/apps/files_sharing/lib/Activity/Providers/Downloads.php @@ -87,7 +87,7 @@ class Downloads implements IProvider { public function parseShortVersion(IEvent $event) { $parsedParameters = $this->getParsedParameters($event); - if ($event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED || + if ($event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED || $event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED) { $event->setParsedSubject($this->l->t('Downloaded via public link')) ->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/download.svg'))); @@ -114,7 +114,7 @@ class Downloads implements IProvider { public function parseLongVersion(IEvent $event) { $parsedParameters = $this->getParsedParameters($event); - if ($event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED || + if ($event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED || $event->getSubject() === self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED) { $event->setParsedSubject($this->l->t('%1$s downloaded via public link', [ $parsedParameters['file']['path'], @@ -150,6 +150,11 @@ class Downloads implements IProvider { $parameters = $event->getSubjectParameters(); switch ($subject) { + case self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED: + case self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED: + return [ + 'file' => $this->generateFileParameter($event->getObjectId(), $parameters[0]), + ]; case self::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED: case self::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED: return [ @@ -161,7 +166,8 @@ class Downloads implements IProvider { ], ]; } - return []; + + throw new \InvalidArgumentException(); } /** diff --git a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php index c7906b84970..8760733a261 100644 --- a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php +++ b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php @@ -159,10 +159,10 @@ class RemoteShares implements IProvider { $subject = $event->getSubject(); $parameters = $event->getSubjectParameters(); - $remoteUser = explode('@', $parameters[0], 2); switch ($subject) { case self::SUBJECT_REMOTE_SHARE_RECEIVED: case self::SUBJECT_REMOTE_SHARE_UNSHARED: + $remoteUser = explode('@', $parameters[0], 2); return [ 'file' => [ 'type' => 'pending-federated-share', @@ -178,6 +178,7 @@ class RemoteShares implements IProvider { ]; case self::SUBJECT_REMOTE_SHARE_ACCEPTED: case self::SUBJECT_REMOTE_SHARE_DECLINED: + $remoteUser = explode('@', $parameters[0], 2); return [ 'file' => $this->generateFileParameter($event->getObjectId(), $event->getObjectName()), 'user' => [ @@ -188,7 +189,7 @@ class RemoteShares implements IProvider { ], ]; } - return []; + throw new \InvalidArgumentException(); } /** diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index 58e843c5d9d..73e3ed3a4b4 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -211,7 +211,9 @@ class ThemingController extends Controller { $tmpFile = $this->tempManager->getTemporaryFile(); if(function_exists('imagescale')) { // FIXME: Once PHP 5.5.0 is a requirement the above check can be removed - $image = imagescale($image, 1920); + // Workaround for https://bugs.php.net/bug.php?id=65171 + $newHeight = imagesy($image)/(imagesx($image)/1920); + $image = imagescale($image, 1920, $newHeight); } imageinterlace($image, 1); imagejpeg($image, $tmpFile, 75); diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 6377d16dd4c..f83a2675958 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -265,17 +265,11 @@ var text = item.label; if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) { - text = t('core', '{sharee} (group)', { - sharee: text - }); + text = t('core', '{sharee} (group)', { sharee: text }, undefined, { escape: false }); } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) { - text = t('core', '{sharee} (remote)', { - sharee: text - }); + text = t('core', '{sharee} (remote)', { sharee: text }, undefined, { escape: false }); } else if (item.value.shareType === OC.Share.SHARE_TYPE_EMAIL) { - text = t('core', '{sharee} (email)', { - sharee: text - }); + text = t('core', '{sharee} (email)', { sharee: text }, undefined, { escape: false }); } var insert = $("<div class='share-autocomplete-item'/>"); var avatar = $("<div class='avatardiv'></div>").appendTo(insert); diff --git a/lib/base.php b/lib/base.php index d6c6e17eff9..2f5517f4614 100644 --- a/lib/base.php +++ b/lib/base.php @@ -493,10 +493,18 @@ class OC { 'lax', 'strict', ]; + + // Append __Host to the cookie if it meets the requirements + $cookiePrefix = ''; + if($cookieParams['secure'] === true && $cookieParams['path'] === '/') { + $cookiePrefix = '__Host-'; + } + foreach($policies as $policy) { header( sprintf( - 'Set-Cookie: nc_sameSiteCookie%s=true; path=%s; httponly;' . $secureCookie . 'expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=%s', + 'Set-Cookie: %snc_sameSiteCookie%s=true; path=%s; httponly;' . $secureCookie . 'expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=%s', + $cookiePrefix, $policy, $cookieParams['path'], $policy diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index c7a3be163fe..62d7fc7ed30 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -498,6 +498,31 @@ class Request implements \ArrayAccess, \Countable, IRequest { } /** + * Wrapper around session_get_cookie_params + * + * @return array + */ + protected function getCookieParams() { + return session_get_cookie_params(); + } + + /** + * Appends the __Host- prefix to the cookie if applicable + * + * @param string $name + * @return string + */ + protected function getProtectedCookieName($name) { + $cookieParams = $this->getCookieParams(); + $prefix = ''; + if($cookieParams['secure'] === true && $cookieParams['path'] === '/') { + $prefix = '__Host-'; + } + + return $prefix.$name; + } + + /** * Checks if the strict cookie has been sent with the request if the request * is including any cookies. * @@ -508,7 +533,9 @@ class Request implements \ArrayAccess, \Countable, IRequest { if(!$this->cookieCheckRequired()) { return true; } - if($this->getCookie('nc_sameSiteCookiestrict') === 'true' + + $cookieName = $this->getProtectedCookieName('nc_sameSiteCookiestrict'); + if($this->getCookie($cookieName) === 'true' && $this->passesLaxCookieCheck()) { return true; } @@ -526,7 +553,9 @@ class Request implements \ArrayAccess, \Countable, IRequest { if(!$this->cookieCheckRequired()) { return true; } - if($this->getCookie('nc_sameSiteCookielax') === 'true') { + + $cookieName = $this->getProtectedCookieName('nc_sameSiteCookielax'); + if($this->getCookie($cookieName) === 'true') { return true; } return false; diff --git a/settings/Application.php b/settings/Application.php index 14110c6ca95..d907cd666fb 100644 --- a/settings/Application.php +++ b/settings/Application.php @@ -34,21 +34,9 @@ use OC\App\AppStore\Fetcher\AppFetcher; use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\AppFramework\Utility\TimeFactory; use OC\Authentication\Token\IProvider; -use OC\Files\View; use OC\Server; -use OC\Settings\Controller\AppSettingsController; -use OC\Settings\Controller\AuthSettingsController; -use OC\Settings\Controller\CertificateController; -use OC\Settings\Controller\CheckSetupController; -use OC\Settings\Controller\EncryptionController; -use OC\Settings\Controller\GroupsController; -use OC\Settings\Controller\LogSettingsController; -use OC\Settings\Controller\MailSettingsController; -use OC\Settings\Controller\SecuritySettingsController; -use OC\Settings\Controller\UsersController; use OC\Settings\Middleware\SubadminMiddleware; use OCP\AppFramework\App; -use OCP\AppFramework\IAppContainer; use OCP\IContainer; use OCP\Settings\IManager; use OCP\Util; @@ -72,130 +60,6 @@ class Application extends App { $container->registerMiddleWare('SubadminMiddleware'); /** - * Controllers - */ - $container->registerService('MailSettingsController', function(IContainer $c) { - return new MailSettingsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('L10N'), - $c->query('Config'), - $c->query('UserSession'), - $c->query('Defaults'), - $c->query('Mailer'), - $c->query('DefaultMailAddress') - ); - }); - $container->registerService('EncryptionController', function(IContainer $c) { - return new EncryptionController( - $c->query('AppName'), - $c->query('Request'), - $c->query('L10N'), - $c->query('Config'), - $c->query('DatabaseConnection'), - $c->query('UserManager'), - new View(), - $c->query('Logger') - ); - }); - - $container->registerService('AppSettingsController', function(IContainer $c) { - return new AppSettingsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('L10N'), - $c->query('Config'), - $c->query('INavigationManager'), - $c->query('IAppManager'), - $c->query('CategoryFetcher'), - $c->query('AppFetcher'), - \OC::$server->getL10NFactory() - ); - }); - $container->registerService('AuthSettingsController', function(IContainer $c) { - return new AuthSettingsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('ServerContainer')->query('OC\Authentication\Token\IProvider'), - $c->query('UserManager'), - $c->query('ServerContainer')->getSession(), - $c->query('ServerContainer')->getSecureRandom(), - $c->query('UserId') - ); - }); - $container->registerService('SecuritySettingsController', function(IContainer $c) { - return new SecuritySettingsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('Config') - ); - }); - $container->registerService('AccountManager', function(IAppContainer $c) { - return new AccountManager($c->getServer()->getDatabaseConnection()); - }); - $container->registerService('CertificateController', function(IContainer $c) { - return new CertificateController( - $c->query('AppName'), - $c->query('Request'), - $c->query('CertificateManager'), - $c->query('SystemCertificateManager'), - $c->query('L10N'), - $c->query('IAppManager') - ); - }); - $container->registerService('GroupsController', function(IContainer $c) { - return new GroupsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('GroupManager'), - $c->query('UserSession'), - $c->query('IsAdmin'), - $c->query('L10N') - ); - }); - $container->registerService('UsersController', function(IContainer $c) { - return new UsersController( - $c->query('AppName'), - $c->query('Request'), - $c->query('UserManager'), - $c->query('GroupManager'), - $c->query('UserSession'), - $c->query('Config'), - $c->query('IsAdmin'), - $c->query('L10N'), - $c->query('Logger'), - $c->query('Defaults'), - $c->query('Mailer'), - $c->query('DefaultMailAddress'), - $c->query('URLGenerator'), - $c->query('OCP\\App\\IAppManager'), - $c->query('OCP\\IAvatarManager'), - $c->query('AccountManager') - ); - }); - $container->registerService('LogSettingsController', function(IContainer $c) { - return new LogSettingsController( - $c->query('AppName'), - $c->query('Request'), - $c->query('Config'), - $c->query('L10N') - ); - }); - $container->registerService('CheckSetupController', function(IContainer $c) { - return new CheckSetupController( - $c->query('AppName'), - $c->query('Request'), - $c->query('Config'), - $c->query('ClientService'), - $c->query('URLGenerator'), - $c->query('Util'), - $c->query('L10N'), - $c->query('Checker') - ); - }); - - - /** * Core class wrappers */ /** FIXME: Remove once OC_User is non-static and mockable */ diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index 1ba20869439..b1515b0efb5 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -1500,6 +1500,76 @@ class RequestTest extends \Test\TestCase { $this->assertFalse($request->passesCSRFCheck()); } + public function testPassesStrictCookieCheckWithAllCookiesAndStrict() { + /** @var Request $request */ + $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') + ->setMethods(['getScriptName', 'getCookieParams']) + ->setConstructorArgs([ + [ + 'server' => [ + 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds', + ], + 'cookies' => [ + session_name() => 'asdf', + '__Host-nc_sameSiteCookiestrict' => 'true', + '__Host-nc_sameSiteCookielax' => 'true', + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ]) + ->getMock(); + $request + ->expects($this->any()) + ->method('getCookieParams') + ->willReturn([ + 'secure' => true, + 'path' => '/', + ]); + + $this->assertTrue($request->passesStrictCookieCheck()); + } + + public function testFailsStrictCookieCheckWithAllCookiesAndMissingStrict() { + /** @var Request $request */ + $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') + ->setMethods(['getScriptName', 'getCookieParams']) + ->setConstructorArgs([ + [ + 'server' => [ + 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds', + ], + 'cookies' => [ + session_name() => 'asdf', + 'nc_sameSiteCookiestrict' => 'true', + 'nc_sameSiteCookielax' => 'true', + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ]) + ->getMock(); + $request + ->expects($this->any()) + ->method('getCookieParams') + ->willReturn([ + 'secure' => true, + 'path' => '/', + ]); + + $this->assertFalse($request->passesStrictCookieCheck()); + } + + public function testGetCookieParams() { + $request = $this->createMock(Request::class); + $actual = $this->invokePrivate($request, 'getCookieParams'); + $this->assertSame(session_get_cookie_params(), $actual); + } + public function testPassesStrictCookieCheckWithAllCookies() { /** @var Request $request */ $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') |