aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dav/appinfo/info.xml4
-rw-r--r--apps/dav/lib/CardDAV/Converter.php2
-rw-r--r--apps/dav/lib/Migration/Classification.php94
-rw-r--r--apps/dav/lib/Migration/GenerateBirthdays.php71
-rw-r--r--apps/dav/tests/unit/CardDAV/ConverterTest.php46
-rw-r--r--apps/dav/tests/unit/Migration/ClassificationTest.php65
-rw-r--r--apps/encryption/lib/Crypto/Encryption.php8
-rw-r--r--apps/encryption/lib/Session.php10
-rw-r--r--apps/encryption/tests/Crypto/EncryptionTest.php15
-rw-r--r--apps/encryption/tests/SessionTest.php26
-rw-r--r--apps/files/css/files.css12
-rw-r--r--apps/files/lib/Activity/Provider.php35
-rw-r--r--apps/files_sharing/lib/Activity/Providers/Downloads.php12
-rw-r--r--apps/files_sharing/lib/Activity/Providers/Groups.php6
-rw-r--r--apps/files_sharing/lib/Activity/Providers/RemoteShares.php5
-rw-r--r--apps/files_sharing/lib/Activity/Providers/Users.php2
-rw-r--r--apps/systemtags/appinfo/app.php6
-rw-r--r--apps/systemtags/css/systemtagsfilelist.css2
-rw-r--r--apps/systemtags/lib/Activity/Provider.php35
-rw-r--r--apps/theming/lib/Controller/ThemingController.php4
-rw-r--r--apps/user_ldap/css/settings.css5
-rw-r--r--apps/user_ldap/js/wizard/wizardTabAdvanced.js15
-rw-r--r--apps/user_ldap/lib/Access.php29
-rw-r--r--apps/user_ldap/lib/Configuration.php4
-rw-r--r--apps/user_ldap/lib/Connection.php1
-rw-r--r--apps/user_ldap/lib/Exceptions/ConstraintViolationException.php26
-rw-r--r--apps/user_ldap/lib/ILDAPWrapper.php9
-rw-r--r--apps/user_ldap/lib/LDAP.php17
-rw-r--r--apps/user_ldap/lib/User_LDAP.php32
-rw-r--r--apps/user_ldap/lib/User_Proxy.php11
-rw-r--r--apps/user_ldap/templates/settings.php2
-rw-r--r--apps/user_ldap/tests/AccessTest.php109
-rw-r--r--apps/user_ldap/tests/LDAPTest.php50
-rw-r--r--apps/user_ldap/tests/User_LDAPTest.php142
-rw-r--r--apps/user_ldap/tests/User_ProxyTest.php61
-rw-r--r--core/css/inputs.css7
-rw-r--r--core/js/jquery.avatar.js6
-rw-r--r--core/js/sharedialogview.js12
-rw-r--r--core/js/tests/specs/jquery.avatarSpec.js4
-rw-r--r--core/templates/installation.php4
-rw-r--r--lib/base.php10
-rw-r--r--lib/private/AppFramework/Http/Request.php33
-rw-r--r--settings/Application.php136
-rw-r--r--settings/js/users/users.js2
-rw-r--r--settings/templates/personal.php28
-rw-r--r--tests/lib/AppFramework/Http/RequestTest.php70
-rw-r--r--version.php2
47 files changed, 826 insertions, 461 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/lib/Activity/Provider.php b/apps/files/lib/Activity/Provider.php
index c2e753e9165..f1ffb851203 100644
--- a/apps/files/lib/Activity/Provider.php
+++ b/apps/files/lib/Activity/Provider.php
@@ -26,6 +26,8 @@ use OCP\Activity\IManager;
use OCP\Activity\IProvider;
use OCP\IL10N;
use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
class Provider implements IProvider {
@@ -38,15 +40,23 @@ class Provider implements IProvider {
/** @var IManager */
protected $activityManager;
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var string[] cached displayNames - key is the UID and value the displayname */
+ protected $displayNames = [];
+
/**
* @param IL10N $l
* @param IURLGenerator $url
* @param IManager $activityManager
+ * @param IUserManager $userManager
*/
- public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager) {
+ public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager, IUserManager $userManager) {
$this->l = $l;
$this->url = $url;
$this->activityManager = $activityManager;
+ $this->userManager = $userManager;
}
/**
@@ -265,11 +275,28 @@ class Provider implements IProvider {
];
}
- protected function getRichUserParameter($parameter) {
+ protected function getRichUserParameter($uid) {
+ if (!isset($this->displayNames[$uid])) {
+ $this->displayNames[$uid] = $this->getDisplayName($uid);
+ }
+
return [
'type' => 'user',
- 'id' => $parameter,
- 'name' => $parameter,// FIXME Use display name
+ 'id' => $uid,
+ 'name' => $this->displayNames[$uid],
];
}
+
+ /**
+ * @param string $uid
+ * @return string
+ */
+ protected function getDisplayName($uid) {
+ $user = $this->userManager->get($uid);
+ if ($user instanceof IUser) {
+ return $user->getDisplayName();
+ } else {
+ return $uid;
+ }
+ }
}
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/Groups.php b/apps/files_sharing/lib/Activity/Providers/Groups.php
index 50b3df785e5..c42cc1bb59b 100644
--- a/apps/files_sharing/lib/Activity/Providers/Groups.php
+++ b/apps/files_sharing/lib/Activity/Providers/Groups.php
@@ -110,17 +110,17 @@ class Groups implements IProvider {
])
->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
} else if ($event->getSubject() === self::SUBJECT_RESHARED_GROUP_BY) {
- $event->setParsedSubject($this->l->t('%2$s shared with %1$s by', [
+ $event->setParsedSubject($this->l->t('%2$s shared with group %1$s', [
$parsedParameters['group']['name'],
$parsedParameters['actor']['name'],
]))
- ->setRichSubject($this->l->t('{actor} shared with {group}'), [
+ ->setRichSubject($this->l->t('{actor} shared with group {group}'), [
'group' => $parsedParameters['group'],
'actor' => $parsedParameters['actor'],
])
->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
} else if ($event->getSubject() === self::SUBJECT_UNSHARED_GROUP_BY) {
- $event->setParsedSubject($this->l->t('%2$s removed share for %1$s', [
+ $event->setParsedSubject($this->l->t('%2$s removed share for group %1$s', [
$parsedParameters['group']['name'],
$parsedParameters['actor']['name'],
]))
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/files_sharing/lib/Activity/Providers/Users.php b/apps/files_sharing/lib/Activity/Providers/Users.php
index 915dbcf225a..c85452aec06 100644
--- a/apps/files_sharing/lib/Activity/Providers/Users.php
+++ b/apps/files_sharing/lib/Activity/Providers/Users.php
@@ -112,7 +112,7 @@ class Users implements IProvider {
])
->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
} else if ($event->getSubject() === self::SUBJECT_RESHARED_USER_BY) {
- $event->setParsedSubject($this->l->t('%2$s shared with %1$s by', [
+ $event->setParsedSubject($this->l->t('%2$s shared with %1$s', [
$parsedParameters['user']['name'],
$parsedParameters['actor']['name'],
]))
diff --git a/apps/systemtags/appinfo/app.php b/apps/systemtags/appinfo/app.php
index 039df2ac9f7..2c095753ce8 100644
--- a/apps/systemtags/appinfo/app.php
+++ b/apps/systemtags/appinfo/app.php
@@ -21,8 +21,6 @@
*
*/
-use OCA\SystemTags\Activity\Extension;
-use OCA\SystemTags\Activity\Listener;
use OCP\SystemTag\ManagerEvent;
use OCP\SystemTag\MapperEvent;
@@ -46,7 +44,7 @@ $eventDispatcher->addListener(
}
);
-$managerListener = function(ManagerEvent $event) use ($activityManager) {
+$managerListener = function(ManagerEvent $event) {
$application = new \OCP\AppFramework\App('systemtags');
/** @var \OCA\SystemTags\Activity\Listener $listener */
$listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener');
@@ -57,7 +55,7 @@ $eventDispatcher->addListener(ManagerEvent::EVENT_CREATE, $managerListener);
$eventDispatcher->addListener(ManagerEvent::EVENT_DELETE, $managerListener);
$eventDispatcher->addListener(ManagerEvent::EVENT_UPDATE, $managerListener);
-$mapperListener = function(MapperEvent $event) use ($activityManager) {
+$mapperListener = function(MapperEvent $event) {
$application = new \OCP\AppFramework\App('systemtags');
/** @var \OCA\SystemTags\Activity\Listener $listener */
$listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener');
diff --git a/apps/systemtags/css/systemtagsfilelist.css b/apps/systemtags/css/systemtagsfilelist.css
index 2da8cd40012..6318d43687e 100644
--- a/apps/systemtags/css/systemtagsfilelist.css
+++ b/apps/systemtags/css/systemtagsfilelist.css
@@ -9,6 +9,7 @@
*/
#app-content-systemtagsfilter .select2-container {
width: 30%;
+ margin-left: 10px;
}
#app-content-systemtagsfilter .select2-choices {
@@ -19,7 +20,6 @@
box-sizing: content-box;
border-radius: 3px;
border: 1px solid #ddd;
- margin: 3px 3px 3px 0;
padding: 0;
min-height: auto;
}
diff --git a/apps/systemtags/lib/Activity/Provider.php b/apps/systemtags/lib/Activity/Provider.php
index 9d85300d5be..37ede8c3b8f 100644
--- a/apps/systemtags/lib/Activity/Provider.php
+++ b/apps/systemtags/lib/Activity/Provider.php
@@ -26,6 +26,8 @@ use OCP\Activity\IManager;
use OCP\Activity\IProvider;
use OCP\IL10N;
use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
class Provider implements IProvider {
@@ -45,15 +47,23 @@ class Provider implements IProvider {
/** @var IManager */
protected $activityManager;
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var string[] */
+ protected $displayNames = [];
+
/**
* @param IL10N $l
* @param IURLGenerator $url
* @param IManager $activityManager
+ * @param IUserManager $userManager
*/
- public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager) {
+ public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager, IUserManager $userManager) {
$this->l = $l;
$this->url = $url;
$this->activityManager = $activityManager;
+ $this->userManager = $userManager;
}
/**
@@ -278,11 +288,15 @@ class Provider implements IProvider {
];
}
- protected function getUserParameter($parameter) {
+ protected function getUserParameter($uid) {
+ if (!isset($this->displayNames[$uid])) {
+ $this->displayNames[$uid] = $this->getDisplayName($uid);
+ }
+
return [
'type' => 'user',
- 'id' => $parameter,
- 'name' => $parameter,// FIXME Use display name
+ 'id' => $uid,
+ 'name' => $this->displayNames[$uid],
];
}
@@ -295,4 +309,17 @@ class Provider implements IProvider {
return $this->l->t('%s (invisible)', $parameter['name']);
}
}
+
+ /**
+ * @param string $uid
+ * @return string
+ */
+ protected function getDisplayName($uid) {
+ $user = $this->userManager->get($uid);
+ if ($user instanceof IUser) {
+ return $user->getDisplayName();
+ } else {
+ return $uid;
+ }
+ }
}
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/apps/user_ldap/css/settings.css b/apps/user_ldap/css/settings.css
index c99efc48c5b..129064ff8b0 100644
--- a/apps/user_ldap/css/settings.css
+++ b/apps/user_ldap/css/settings.css
@@ -3,6 +3,11 @@
width: 85%;
}
+.inlinetable {
+ display: inline-table;
+ vertical-align: bottom;
+}
+
.tablerow {
display: table-row;
white-space: nowrap;
diff --git a/apps/user_ldap/js/wizard/wizardTabAdvanced.js b/apps/user_ldap/js/wizard/wizardTabAdvanced.js
index d1e5002d40a..d0922bbff32 100644
--- a/apps/user_ldap/js/wizard/wizardTabAdvanced.js
+++ b/apps/user_ldap/js/wizard/wizardTabAdvanced.js
@@ -95,6 +95,10 @@ OCA = OCA || {};
$element: $('#ldap_paging_size'),
setMethod: 'setPagingSize'
},
+ ldap_turn_on_pwd_change: {
+ $element: $('#ldap_turn_on_pwd_change'),
+ setMethod: 'setPasswordChangeEnabled'
+ },
//Special Attributes
ldap_quota_attr: {
@@ -288,6 +292,17 @@ OCA = OCA || {};
setPagingSize: function(size) {
this.setElementValue(this.managedItems.ldap_paging_size.$element, size);
},
+
+ /**
+ * sets whether the password changes per user should be enabled
+ *
+ * @param {string} doPasswordChange contains an int
+ */
+ setPasswordChangeEnabled: function(doPasswordChange) {
+ this.setElementValue(
+ this.managedItems.ldap_turn_on_pwd_change.$element, doPasswordChange
+ );
+ },
/**
* sets the email attribute
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index e7facd80ae0..d88378c1888 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -40,6 +40,8 @@
namespace OCA\User_LDAP;
+use OC\HintException;
+use OCA\User_LDAP\Exceptions\ConstraintViolationException;
use OCA\User_LDAP\User\IUserTools;
use OCA\User_LDAP\User\Manager;
use OCA\User_LDAP\User\OfflineUser;
@@ -221,6 +223,33 @@ class Access extends LDAPUtility implements IUserTools {
\OCP\Util::writeLog('user_ldap', 'Requested attribute '.$attr.' not found for '.$dn, \OCP\Util::DEBUG);
return false;
}
+
+ /**
+ * Set password for an LDAP user identified by a DN
+ *
+ * @param string $userDN the user in question
+ * @param string $password the new password
+ * @return bool
+ * @throws HintException
+ * @throws \Exception
+ */
+ public function setPassword($userDN, $password) {
+ if(intval($this->connection->turnOnPasswordChange) !== 1) {
+ throw new \Exception('LDAP password changes are disabled.');
+ }
+ $cr = $this->connection->getConnectionResource();
+ if(!$this->ldap->isResource($cr)) {
+ //LDAP not available
+ \OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG);
+ return false;
+ }
+
+ try {
+ return $this->ldap->modReplace($cr, $userDN, $password);
+ } catch(ConstraintViolationException $e) {
+ throw new HintException('Password change rejected.', \OC::$server->getL10N('user_ldap')->t('Password change rejected. Hint: ').$e->getMessage(), $e->getCode());
+ }
+ }
/**
* checks whether the given attributes value is probably a DN
diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php
index 80b353360c3..eb4fcd3fbe6 100644
--- a/apps/user_ldap/lib/Configuration.php
+++ b/apps/user_ldap/lib/Configuration.php
@@ -11,6 +11,7 @@
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -90,6 +91,7 @@ class Configuration {
'lastJpegPhotoLookup' => null,
'ldapNestedGroups' => false,
'ldapPagingSize' => null,
+ 'turnOnPasswordChange' => false,
'ldapDynamicGroupMemberURL' => null,
);
@@ -449,6 +451,7 @@ class Configuration {
'last_jpegPhoto_lookup' => 0,
'ldap_nested_groups' => 0,
'ldap_paging_size' => 500,
+ 'ldap_turn_on_pwd_change' => 0,
'ldap_experienced_admin' => 0,
'ldap_dynamic_group_member_url' => '',
);
@@ -505,6 +508,7 @@ class Configuration {
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
'ldap_nested_groups' => 'ldapNestedGroups',
'ldap_paging_size' => 'ldapPagingSize',
+ 'ldap_turn_on_pwd_change' => 'turnOnPasswordChange',
'ldap_experienced_admin' => 'ldapExperiencedAdmin',
'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL',
);
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index 6028486e8bb..d74afa42fe8 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -42,6 +42,7 @@ use OC\ServerNotAvailableException;
* @property string ldapUserFilter
* @property string ldapUserDisplayName
* @property string ldapUserDisplayName2
+ * @property boolean turnOnPasswordChange
* @property boolean hasPagedResultSupport
* @property string[] ldapBaseUsers
* @property int|string ldapPagingSize holds an integer
diff --git a/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php
new file mode 100644
index 00000000000..997b01b2d4e
--- /dev/null
+++ b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Roger Szabo <roger.szabo@web.de>
+ *
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @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 OCA\User_LDAP\Exceptions;
+
+class ConstraintViolationException extends \Exception {}
diff --git a/apps/user_ldap/lib/ILDAPWrapper.php b/apps/user_ldap/lib/ILDAPWrapper.php
index 4fd3b31428a..e2089fa8a47 100644
--- a/apps/user_ldap/lib/ILDAPWrapper.php
+++ b/apps/user_ldap/lib/ILDAPWrapper.php
@@ -163,6 +163,15 @@ interface ILDAPWrapper {
* @return resource|false an LDAP search result resource, false on error
*/
public function search($link, $baseDN, $filter, $attr, $attrsOnly = 0, $limit = 0);
+
+ /**
+ * Replace the value of a userPassword by $password
+ * @param resource $link LDAP link resource
+ * @param string $userDN the DN of the user whose password is to be replaced
+ * @param string $password the new value for the userPassword
+ * @return bool true on success, false otherwise
+ */
+ public function modReplace($link, $userDN, $password);
/**
* Sets the value of the specified option to be $value
diff --git a/apps/user_ldap/lib/LDAP.php b/apps/user_ldap/lib/LDAP.php
index 74d83e4ab4f..cac09f25993 100644
--- a/apps/user_ldap/lib/LDAP.php
+++ b/apps/user_ldap/lib/LDAP.php
@@ -9,6 +9,7 @@
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -29,6 +30,7 @@
namespace OCA\User_LDAP;
use OC\ServerNotAvailableException;
+use OCA\User_LDAP\Exceptions\ConstraintViolationException;
class LDAP implements ILDAPWrapper {
protected $curFunc = '';
@@ -194,6 +196,16 @@ class LDAP implements ILDAPWrapper {
/**
* @param LDAP $link
+ * @param string $userDN
+ * @param string $password
+ * @return bool
+ */
+ public function modReplace($link, $userDN, $password) {
+ return $this->invokeLDAPMethod('mod_replace', $link, $userDN, array('userPassword' => $password));
+ }
+
+ /**
+ * @param LDAP $link
* @param string $option
* @param int $value
* @return bool|mixed
@@ -248,7 +260,7 @@ class LDAP implements ILDAPWrapper {
/**
* @return mixed
*/
- private function invokeLDAPMethod() {
+ protected function invokeLDAPMethod() {
$arguments = func_get_args();
$func = 'ldap_' . array_shift($arguments);
if(function_exists($func)) {
@@ -288,6 +300,9 @@ class LDAP implements ILDAPWrapper {
throw new \Exception('LDAP authentication method rejected', $errorCode);
} else if ($errorCode === 1) {
throw new \Exception('LDAP Operations error', $errorCode);
+ } else if ($errorCode === 19) {
+ ldap_get_option($this->curArgs[0], LDAP_OPT_ERROR_STRING, $extended_error);
+ throw new ConstraintViolationException(!empty($extended_error)?$extended_error:$errorMsg, $errorCode);
} else {
\OCP\Util::writeLog('user_ldap',
'LDAP error '.$errorMsg.' (' .
diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php
index 9f2468bcc85..8dfde2d8148 100644
--- a/apps/user_ldap/lib/User_LDAP.php
+++ b/apps/user_ldap/lib/User_LDAP.php
@@ -35,6 +35,7 @@
namespace OCA\User_LDAP;
+use OC\User\Backend;
use OC\User\NoUserException;
use OCA\User_LDAP\Exceptions\NotOnLDAP;
use OCA\User_LDAP\User\OfflineUser;
@@ -175,6 +176,26 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
}
/**
+ * Set password
+ * @param string $uid The username
+ * @param string $password The new password
+ * @return bool
+ */
+ public function setPassword($uid, $password) {
+ $user = $this->access->userManager->get($uid);
+
+ if(!$user instanceof User) {
+ throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
+ '. Maybe the LDAP entry has no set display name attribute?');
+ }
+ if($user->getUsername() !== false) {
+ return $this->access->setPassword($user->getDN(), $password);
+ }
+
+ return false;
+ }
+
+ /**
* Get a list of all users
*
* @param string $search
@@ -449,11 +470,12 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
* compared with OC_USER_BACKEND_CREATE_USER etc.
*/
public function implementsActions($actions) {
- return (bool)((\OC\User\Backend::CHECK_PASSWORD
- | \OC\User\Backend::GET_HOME
- | \OC\User\Backend::GET_DISPLAYNAME
- | \OC\User\Backend::PROVIDE_AVATAR
- | \OC\User\Backend::COUNT_USERS)
+ return (bool)((Backend::CHECK_PASSWORD
+ | Backend::GET_HOME
+ | Backend::GET_DISPLAYNAME
+ | Backend::PROVIDE_AVATAR
+ | Backend::COUNT_USERS
+ | ((intval($this->access->connection->turnOnPasswordChange) === 1)?(Backend::SET_PASSWORD):0))
& $actions);
}
diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php
index cced469a7ae..2cdf401880e 100644
--- a/apps/user_ldap/lib/User_Proxy.php
+++ b/apps/user_ldap/lib/User_Proxy.php
@@ -262,6 +262,17 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface,
public function deleteUser($uid) {
return $this->handleRequest($uid, 'deleteUser', array($uid));
}
+
+ /**
+ * Set password
+ * @param string $uid The username
+ * @param string $password The new password
+ * @return bool
+ *
+ */
+ public function setPassword($uid, $password) {
+ return $this->handleRequest($uid, 'setPassword', array($uid, $password));
+ }
/**
* @return bool
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index eb4c7b99127..e53456c703c 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -101,6 +101,8 @@ style('user_ldap', 'settings');
<p><label for="ldap_dynamic_group_member_url"><?php p($l->t('Dynamic Group Member URL'));?></label><input type="text" id="ldap_dynamic_group_member_url" name="ldap_dynamic_group_member_url" title="<?php p($l->t('The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)'));?>" data-default="<?php p($_['ldap_dynamic_group_member_url_default']); ?>" /></p>
<p><label for="ldap_nested_groups"><?php p($l->t('Nested Groups'));?></label><input type="checkbox" id="ldap_nested_groups" name="ldap_nested_groups" value="1" data-default="<?php p($_['ldap_nested_groups_default']); ?>" title="<?php p($l->t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)'));?>" /></p>
<p><label for="ldap_paging_size"><?php p($l->t('Paging chunksize'));?></label><input type="number" id="ldap_paging_size" name="ldap_paging_size" title="<?php p($l->t('Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)'));?>" data-default="<?php p($_['ldap_paging_size_default']); ?>" /></p>
+ <p><label for="ldap_turn_on_pwd_change"><?php p($l->t('Enable LDAP password changes per user'));?></label><span class="inlinetable"><span class="tablerow left"><input type="checkbox" id="ldap_turn_on_pwd_change" name="ldap_turn_on_pwd_change" value="1" data-default="<?php p($_['ldap_turn_on_pwd_change_default']); ?>" title="<?php p($l->t('Allow LDAP users to change their password and allow Super Administrators and Group Administrators to change the password of their LDAP users. Only works when access control policies are configured accordingly on the LDAP server. As passwords are sent in plaintext to the LDAP server, transport encryption must be used and password hashing should be configured on the LDAP server.'));?>" /><span class="tablecell"><?php p($l->t('(New password is sent as plain text to LDAP)'));?></span></span>
+ </span><br/></p>
</div>
<h3><?php p($l->t('Special Attributes'));?></h3>
<div>
diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php
index d7d04e31d08..271e8eb605b 100644
--- a/apps/user_ldap/tests/AccessTest.php
+++ b/apps/user_ldap/tests/AccessTest.php
@@ -1,12 +1,14 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch>
*
* @author Andreas Fischer <bantu@owncloud.com>
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
* @author Joas Schilling <coding@schilljs.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Lukas Reschke <lukas@statuscode.ch>
*
* @license AGPL-3.0
*
@@ -28,9 +30,11 @@ namespace OCA\User_LDAP\Tests;
use OCA\User_LDAP\Access;
use OCA\User_LDAP\Connection;
+use OCA\User_LDAP\Exceptions\ConstraintViolationException;
use OCA\User_LDAP\FilesystemHelper;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\ILDAPWrapper;
+use OCA\User_LDAP\LDAP;
use OCA\User_LDAP\LogWrapper;
use OCA\User_LDAP\User\Manager;
use OCP\IAvatarManager;
@@ -47,6 +51,31 @@ use OCP\IUserManager;
* @package OCA\User_LDAP\Tests
*/
class AccessTest extends \Test\TestCase {
+ /** @var Connection|\PHPUnit_Framework_MockObject_MockObject */
+ private $connection;
+ /** @var LDAP|\PHPUnit_Framework_MockObject_MockObject */
+ private $ldap;
+ /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */
+ private $userManager;
+ /** @var Helper|\PHPUnit_Framework_MockObject_MockObject */
+ private $helper;
+ /** @var Access */
+ private $access;
+
+ public function setUp() {
+ $this->connection = $this->createMock(Connection::class);
+ $this->ldap = $this->createMock(LDAP::class);
+ $this->userManager = $this->createMock(Manager::class);
+ $this->helper = $this->createMock(Helper::class);
+
+ $this->access = new Access(
+ $this->connection,
+ $this->ldap,
+ $this->userManager,
+ $this->helper
+ );
+ }
+
private function getConnectorAndLdapMock() {
$lw = $this->createMock(ILDAPWrapper::class);
$connector = $this->getMockBuilder(Connection::class)
@@ -317,4 +346,84 @@ class AccessTest extends \Test\TestCase {
$values = $access->readAttribute('uid=whoever,dc=example,dc=org', $attribute);
$this->assertSame($values[0], strtolower($dnFromServer));
}
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage LDAP password changes are disabled
+ */
+ public function testSetPasswordWithDisabledChanges() {
+ $this->connection
+ ->method('__get')
+ ->willReturn(false);
+
+ $this->access->setPassword('CN=foo', 'MyPassword');
+ }
+
+ public function testSetPasswordWithLdapNotAvailable() {
+ $this->connection
+ ->method('__get')
+ ->willReturn(true);
+ $connection = $this->createMock(LDAP::class);
+ $this->connection
+ ->expects($this->once())
+ ->method('getConnectionResource')
+ ->willReturn($connection);
+ $this->ldap
+ ->expects($this->once())
+ ->method('isResource')
+ ->with($connection)
+ ->willReturn(false);
+
+ $this->assertFalse($this->access->setPassword('CN=foo', 'MyPassword'));
+ }
+
+ /**
+ * @expectedException \OC\HintException
+ * @expectedExceptionMessage Password change rejected.
+ */
+ public function testSetPasswordWithRejectedChange() {
+ $this->connection
+ ->method('__get')
+ ->willReturn(true);
+ $connection = $this->createMock(LDAP::class);
+ $this->connection
+ ->expects($this->once())
+ ->method('getConnectionResource')
+ ->willReturn($connection);
+ $this->ldap
+ ->expects($this->once())
+ ->method('isResource')
+ ->with($connection)
+ ->willReturn(true);
+ $this->ldap
+ ->expects($this->once())
+ ->method('modReplace')
+ ->with($connection, 'CN=foo', 'MyPassword')
+ ->willThrowException(new ConstraintViolationException());
+
+ $this->access->setPassword('CN=foo', 'MyPassword');
+ }
+
+ public function testSetPassword() {
+ $this->connection
+ ->method('__get')
+ ->willReturn(true);
+ $connection = $this->createMock(LDAP::class);
+ $this->connection
+ ->expects($this->once())
+ ->method('getConnectionResource')
+ ->willReturn($connection);
+ $this->ldap
+ ->expects($this->once())
+ ->method('isResource')
+ ->with($connection)
+ ->willReturn(true);
+ $this->ldap
+ ->expects($this->once())
+ ->method('modReplace')
+ ->with($connection, 'CN=foo', 'MyPassword')
+ ->willReturn(true);
+
+ $this->assertTrue($this->access->setPassword('CN=foo', 'MyPassword'));
+ }
}
diff --git a/apps/user_ldap/tests/LDAPTest.php b/apps/user_ldap/tests/LDAPTest.php
new file mode 100644
index 00000000000..1ac8cef12de
--- /dev/null
+++ b/apps/user_ldap/tests/LDAPTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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 OCA\User_LDAP\Tests;
+
+use OCA\User_LDAP\LDAP;
+use Test\TestCase;
+
+class LDAPTest extends TestCase {
+ /** @var LDAP|\PHPUnit_Framework_MockObject_MockObject */
+ private $ldap;
+
+ public function setUp() {
+ parent::setUp();
+ $this->ldap = $this->getMockBuilder(LDAP::class)
+ ->setMethods(['invokeLDAPMethod'])
+ ->getMock();
+ }
+
+ public function testModReplace() {
+ $link = $this->createMock(LDAP::class);
+ $userDN = 'CN=user';
+ $password = 'MyPassword';
+ $this->ldap
+ ->expects($this->once())
+ ->method('invokeLDAPMethod')
+ ->with('mod_replace', $link, $userDN, array('userPassword' => $password))
+ ->willReturn(true);
+
+ $this->assertTrue($this->ldap->modReplace($link, $userDN, $password));
+ }
+}
diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php
index 05837097929..606eff4e7a7 100644
--- a/apps/user_ldap/tests/User_LDAPTest.php
+++ b/apps/user_ldap/tests/User_LDAPTest.php
@@ -9,6 +9,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -36,8 +37,10 @@ use OCA\User_LDAP\ILDAPWrapper;
use OCA\User_LDAP\LogWrapper;
use OCA\User_LDAP\User\Manager;
use OCA\User_LDAP\User\OfflineUser;
+use OC\HintException;
use OCA\User_LDAP\User\User;
use OCA\User_LDAP\User_LDAP as UserLDAP;
+use OCA\User_LDAP\User_LDAP;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\IDBConnection;
@@ -958,5 +961,144 @@ class User_LDAPTest extends TestCase {
// and once again to verify that caching works
$backend->loginName2UserName($loginName);
}
+
+ /**
+ * Prepares the Access mock for setPassword tests
+ * @param \OCA\User_LDAP\Access|\PHPUnit_Framework_MockObject_MockObject $access mock
+ * @return void
+ */
+ private function prepareAccessForSetPassword(&$access, $enablePasswordChange = true) {
+ $access->connection->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function($name) use (&$enablePasswordChange) {
+ if($name === 'ldapLoginFilter') {
+ return '%uid';
+ }
+ if($name === 'turnOnPasswordChange') {
+ return $enablePasswordChange?1:0;
+ }
+ return null;
+ }));
+
+ $access->connection->expects($this->any())
+ ->method('getFromCache')
+ ->will($this->returnCallback(function($uid) {
+ if($uid === 'userExists'.'roland') {
+ return true;
+ }
+ return null;
+ }));
+
+ $access->expects($this->any())
+ ->method('fetchListOfUsers')
+ ->will($this->returnCallback(function($filter) {
+ if($filter === 'roland') {
+ return array(array('dn' => ['dnOfRoland,dc=test']));
+ }
+ return array();
+ }));
+
+ $access->expects($this->any())
+ ->method('fetchUsersByLoginName')
+ ->will($this->returnCallback(function($uid) {
+ if($uid === 'roland') {
+ return array(array('dn' => ['dnOfRoland,dc=test']));
+ }
+ return array();
+ }));
+
+ $access->expects($this->any())
+ ->method('dn2username')
+ ->with($this->equalTo('dnOfRoland,dc=test'))
+ ->will($this->returnValue('roland'));
+ $access->expects($this->any())
+ ->method('stringResemblesDN')
+ ->with($this->equalTo('dnOfRoland,dc=test'))
+ ->will($this->returnValue(true));
+
+ $access->expects($this->any())
+ ->method('setPassword')
+ ->will($this->returnCallback(function($uid, $password) {
+ if(strlen($password) <= 5) {
+ throw new HintException('Password fails quality checking policy', '', 19);
+ }
+ return true;
+ }));
+ }
+
+ /**
+ * @expectedException \OC\HintException
+ * @expectedExceptionMessage Password fails quality checking policy
+ */
+ public function testSetPasswordInvalid() {
+ $access = $this->getAccessMock();
+
+ $this->prepareAccessForSetPassword($access);
+ $backend = new UserLDAP($access, $this->createMock(IConfig::class));
+ \OC_User::useBackend($backend);
+
+ $this->assertTrue(\OC_User::setPassword('roland', 'dt'));
+ }
+
+ public function testSetPasswordValid() {
+ $access = $this->getAccessMock();
+
+ $this->prepareAccessForSetPassword($access);
+ $backend = new UserLDAP($access, $this->createMock(IConfig::class));
+ \OC_User::useBackend($backend);
+
+ $this->assertTrue(\OC_User::setPassword('roland', 'dt12234$'));
+ }
+
+ public function testSetPasswordValidDisabled() {
+ $access = $this->getAccessMock();
+
+ $this->prepareAccessForSetPassword($access, false);
+ $backend = new UserLDAP($access, $this->createMock(IConfig::class));
+ \OC_User::useBackend($backend);
+
+ $this->assertFalse(\OC_User::setPassword('roland', 'dt12234$'));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage LDAP setPassword: Could not get user object for uid NotExistingUser. Maybe the LDAP entry has no set display name attribute?
+ */
+ public function testSetPasswordWithInvalidUser() {
+ $access = $this->createMock(Access::class);
+ $access->userManager = $this->createMock(IUserManager::class);
+ $access->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('NotExistingUser')
+ ->willReturn(null);
+ $config = $this->createMock(IConfig::class);
+ $ldap = new User_LDAP(
+ $access,
+ $config
+ );
+ $ldap->setPassword('NotExistingUser', 'Password');
+ }
+
+ public function testSetPasswordWithUsernameFalse() {
+ $user = $this->createMock(User::class);
+ $user
+ ->expects($this->once())
+ ->method('getUsername')
+ ->willReturn(false);
+ $access = $this->createMock(Access::class);
+ $access->userManager = $this->createMock(IUserManager::class);
+ $access->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('NotExistingUser')
+ ->willReturn($user);
+ $config = $this->createMock(IConfig::class);
+ $ldap = new User_LDAP(
+ $access,
+ $config
+ );
+ $this->assertFalse($ldap->setPassword('NotExistingUser', 'Password'));
+ }
}
diff --git a/apps/user_ldap/tests/User_ProxyTest.php b/apps/user_ldap/tests/User_ProxyTest.php
new file mode 100644
index 00000000000..6d779d758e4
--- /dev/null
+++ b/apps/user_ldap/tests/User_ProxyTest.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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 OCA\User_LDAP\Tests;
+
+use OCA\User_LDAP\ILDAPWrapper;
+use OCA\User_LDAP\User_Proxy;
+use OCP\IConfig;
+use Test\TestCase;
+
+class User_ProxyTest extends TestCase {
+ /** @var ILDAPWrapper|\PHPUnit_Framework_MockObject_MockObject */
+ private $ldapWrapper;
+ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+ private $config;
+ /** @var User_Proxy|\PHPUnit_Framework_MockObject_MockObject */
+ private $proxy;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->ldapWrapper = $this->createMock(ILDAPWrapper::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->proxy = $this->getMockBuilder(User_Proxy::class)
+ ->setConstructorArgs([
+ [],
+ $this->ldapWrapper,
+ $this->config,
+ ])
+ ->setMethods(['handleRequest'])
+ ->getMock();
+ }
+
+ public function testSetPassword() {
+ $this->proxy
+ ->expects($this->once())
+ ->method('handleRequest')
+ ->with('MyUid', 'setPassword', ['MyUid', 'MyPassword'])
+ ->willReturn(true);
+
+ $this->assertTrue($this->proxy->setPassword('MyUid', 'MyPassword'));
+ }
+}
diff --git a/core/css/inputs.css b/core/css/inputs.css
index 3d74ff38271..f2233395658 100644
--- a/core/css/inputs.css
+++ b/core/css/inputs.css
@@ -243,8 +243,8 @@ select:hover {
#select2-drop .select2-search input {
width: calc(100% - 14px);
min-height: auto;
- background: url('../img/actions/search.svg') no-repeat right center;
- background-origin: content-box;
+ background: url('../img/actions/search.svg') no-repeat right center !important;
+ background-origin: content-box !important;
}
#select2-drop .select2-results {
max-height: 250px;
@@ -252,7 +252,6 @@ select:hover {
padding: 0;
}
#select2-drop .select2-results .select2-result-label {
- padding: 12px !important;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -340,7 +339,7 @@ select:hover {
border: none;
}
.select2-container .select2-choice .select2-arrow b {
- background: url('../img/actions/triangle-s.svg') no-repeat center;
+ background: url('../img/actions/triangle-s.svg') no-repeat center !important;
opacity: .5;
}
.select2-container .select2-choice:hover .select2-arrow b,
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 754400acd7b..1abe70b79ea 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -29,7 +29,7 @@
* 3. $('.avatardiv').avatar();
* This will search the DOM for 'user' data, to use as the username. If there
* is no username available it will default to a placeholder with the value of
- * "x". The size will be determined the same way, as the second example.
+ * "?". The size will be determined the same way, as the second example.
*
* 4. $('.avatardiv').avatar('jdoe', 128, true);
* This will behave like the first example, except it will also append random
@@ -65,7 +65,7 @@
if (typeof(this.data('user')) !== 'undefined') {
user = this.data('user');
} else {
- this.imageplaceholder('x');
+ this.imageplaceholder('?');
return;
}
}
@@ -105,7 +105,7 @@
$div.imageplaceholder(user, result.data.displayname);
} else {
// User does not exist
- $div.imageplaceholder(user, 'X');
+ $div.imageplaceholder(user, '?');
$div.css('background-color', '#b9b9b9');
}
} else {
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/core/js/tests/specs/jquery.avatarSpec.js b/core/js/tests/specs/jquery.avatarSpec.js
index f5caae10020..9bb10c41be7 100644
--- a/core/js/tests/specs/jquery.avatarSpec.js
+++ b/core/js/tests/specs/jquery.avatarSpec.js
@@ -65,7 +65,7 @@ describe('jquery.avatar tests', function() {
$div.avatar();
- expect($div.imageplaceholder).toHaveBeenCalledWith('x');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('?');
});
describe('no avatar', function() {
@@ -96,7 +96,7 @@ describe('jquery.avatar tests', function() {
})
);
- expect($div.imageplaceholder).toHaveBeenCalledWith('foo', 'X');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('foo', '?');
});
it('show no placeholder', function() {
diff --git a/core/templates/installation.php b/core/templates/installation.php
index f7556988634..d3f5021821d 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -147,8 +147,6 @@ script('core', [
<?php endif; ?>
<?php endif; ?>
- <div class="icon-loading-dark float-spinner">&nbsp;</div>
-
<?php if(!$_['dbIsSet'] OR count($_['errors']) > 0): ?>
<fieldset id="sqliteInformation" class="warning">
<legend><?php p($l->t('Performance warning'));?></legend>
@@ -158,6 +156,8 @@ script('core', [
</fieldset>
<?php endif ?>
+ <div class="icon-loading-dark float-spinner">&nbsp;</div>
+
<div class="buttons"><input type="submit" class="primary" value="<?php p($l->t( 'Finish setup' )); ?>" data-finishing="<?php p($l->t( 'Finishing …' )); ?>"></div>
<p class="info">
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 ca2b2b91f71..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;
@@ -69,129 +57,7 @@ class Application extends App {
// Register Middleware
$container->registerAlias('SubadminMiddleware', SubadminMiddleware::class);
- /**
- * 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')
- );
- });
-
+ $container->registerMiddleWare('SubadminMiddleware');
/**
* Core class wrappers
diff --git a/settings/js/users/users.js b/settings/js/users/users.js
index 7e70d98f091..71defeaa18a 100644
--- a/settings/js/users/users.js
+++ b/settings/js/users/users.js
@@ -497,7 +497,7 @@ var UserList = {
group: group
},
function (response) {
- if (response.data.message) {
+ if (response.data !== undefined && response.data.message) {
OC.Notification.show(response.data.message);
}
}
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index b81b19d9060..2ae6c1dcdf2 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -157,34 +157,6 @@ if($_['displayNameChangeSupported']) {
<?php
} else {
?>
-<div id="displaynameform" class="section">
- <h2><?php echo $l->t('Full name');?></h2>
- <span><?php if(isset($_['displayName'][0])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
-</div>
-<?php
-}
-?>
-
-<?php
-if($_['displayNameChangeSupported']) {
-?>
-<form id="lostpassword" class="section">
- <h2>
- <label for="email"><?php p($l->t('Email'));?></label>
- </h2>
- <input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
- placeholder="<?php p($l->t('Your email address'));?>"
- class="password-confirm-required"
- autocomplete="on" autocapitalize="off" autocorrect="off" />
- <span class="msg"></span><br />
- <em><?php p($l->t('For password recovery and notifications'));?></em>
-</form>
-<?php
-} else {
-?>
-<div id="lostpassword" class="section">
- <h2><?php echo $l->t('Email'); ?></h2>
- <span><?php if(isset($_['email'][0])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
<div id="personal-settings-container" class="no-edit">
<div id="displaynameform" class="section">
<h2><?php p($l->t('Full name'));?></h2>
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')
diff --git a/version.php b/version.php
index 0eb9f3de72a..4aef5b12d77 100644
--- a/version.php
+++ b/version.php
@@ -29,7 +29,7 @@
$OC_Version = array(11, 0, 0, 2);
// The human readable string
-$OC_VersionString = '11.0 alpha';
+$OC_VersionString = '11.0 beta';
$OC_VersionCanBeUpgradedFrom = array(9, 1);