summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/comments/js/commentstabview.js9
-rw-r--r--apps/dav/appinfo/application.php5
-rw-r--r--apps/dav/appinfo/info.xml3
-rw-r--r--apps/dav/appinfo/install.php1
-rw-r--r--apps/dav/appinfo/update.php1
-rw-r--r--apps/dav/lib/connector/sabre/principal.php8
-rw-r--r--apps/dav/lib/server.php3
-rw-r--r--apps/dav/tests/unit/connector/sabre/principal.php15
-rw-r--r--apps/files_sharing/api/share20ocs.php72
-rw-r--r--apps/files_sharing/tests/api/share20ocstest.php193
-rw-r--r--apps/provisioning_api/appinfo/routes.php11
-rw-r--r--apps/provisioning_api/lib/users.php72
-rw-r--r--apps/provisioning_api/tests/userstest.php64
-rw-r--r--build/integration/features/bootstrap/Provisioning.php67
-rw-r--r--build/integration/features/bootstrap/WebDav.php10
-rw-r--r--build/integration/features/provisioning-v1.feature194
-rw-r--r--build/integration/features/sharing-v1.feature13
-rw-r--r--build/integration/features/webdav-related.feature8
-rw-r--r--core/Command/Log/Manage.php2
-rw-r--r--core/Command/User/Disable.php64
-rw-r--r--core/Command/User/Enable.php64
-rw-r--r--core/register_command.php2
-rw-r--r--core/templates/login.php4
-rw-r--r--lib/private/App/InfoParser.php11
-rw-r--r--lib/private/Installer.php3
-rw-r--r--lib/private/Lock/AbstractLockingProvider.php3
-rw-r--r--lib/private/Log.php2
-rw-r--r--lib/private/Log/ErrorHandler.php (renamed from lib/private/log/errorhandler.php)0
-rw-r--r--lib/private/Log/Errorlog.php (renamed from lib/private/log/errorlog.php)4
-rw-r--r--lib/private/Log/Owncloud.php (renamed from lib/private/log/owncloud.php)16
-rw-r--r--lib/private/Log/Rotate.php (renamed from lib/private/log/rotate.php)0
-rw-r--r--lib/private/Log/Syslog.php (renamed from lib/private/log/syslog.php)4
-rw-r--r--lib/private/Server.php7
-rw-r--r--lib/private/Share/Constants.php (renamed from lib/private/share/constants.php)0
-rw-r--r--lib/private/Share/Helper.php (renamed from lib/private/share/helper.php)0
-rw-r--r--lib/private/Share/MailNotifications.php (renamed from lib/private/share/mailnotifications.php)0
-rw-r--r--lib/private/Share/SearchResultSorter.php (renamed from lib/private/share/searchresultsorter.php)0
-rw-r--r--lib/private/Share/Share.php (renamed from lib/private/share/share.php)0
-rw-r--r--lib/private/legacy/api.php6
-rw-r--r--lib/private/legacy/app.php8
-rw-r--r--lib/private/legacy/user.php28
-rw-r--r--lib/private/user/database.php12
-rw-r--r--lib/private/user/manager.php14
-rw-r--r--lib/private/user/session.php46
-rw-r--r--lib/private/user/user.php1
-rw-r--r--lib/public/IServerContainer.php12
-rw-r--r--lib/public/iuser.php1
-rw-r--r--lib/public/iusermanager.php7
-rw-r--r--settings/Controller/LogSettingsController.php2
-rw-r--r--tests/data/app/expected-info.json3
-rw-r--r--tests/lib/log/owncloud.php15
-rw-r--r--tests/lib/user/session.php38
52 files changed, 989 insertions, 139 deletions
diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js
index 415ec2a9be5..9475dc53fc0 100644
--- a/apps/comments/js/commentstabview.js
+++ b/apps/comments/js/commentstabview.js
@@ -172,7 +172,7 @@
this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28);
}
this.delegateEvents();
- this.$el.find('textarea').on('keyup input change', this._onTypeComment);
+ this.$el.find('textarea').on('keydown input change', this._onTypeComment);
},
_formatItem: function(commentModel) {
@@ -273,7 +273,7 @@
// spawn form
$comment.after($formRow);
$formRow.data('commentEl', $comment);
- $formRow.find('textarea').on('keyup input change', this._onTypeComment);
+ $formRow.find('textarea').on('keydown input change', this._onTypeComment);
// copy avatar element from original to avoid flickering
$formRow.find('.avatar').replaceWith($comment.find('.avatar').clone());
@@ -301,6 +301,11 @@
var limitExceeded = (len > this._commentMaxLength);
$field.toggleClass('error', limitExceeded);
$submitButton.prop('disabled', limitExceeded);
+
+ //submits form on ctrl+Enter or cmd+Enter
+ if (ev.keyCode === 13 && (ev.ctrlKey || ev.metaKey)) {
+ $submitButton.click();
+ }
},
_onClickComment: function(ev) {
diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php
index c3811a40845..328f86c877f 100644
--- a/apps/dav/appinfo/application.php
+++ b/apps/dav/appinfo/application.php
@@ -153,11 +153,6 @@ class Application extends App {
return $this->getContainer()->query('SyncService');
}
- public function setupCron() {
- $jl = $this->getContainer()->getServer()->getJobList();
- $jl->add(new SyncJob());
- }
-
public function generateBirthdays() {
try {
/** @var BirthdayService $migration */
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index bb447c9a426..e2688e2f923 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -16,4 +16,7 @@
<dependencies>
<owncloud min-version="9.1" max-version="9.1" />
</dependencies>
+ <background-jobs>
+ <job>OCA\DAV\CardDAV\Sync\SyncJob</job>
+ </background-jobs>
</info>
diff --git a/apps/dav/appinfo/install.php b/apps/dav/appinfo/install.php
index fbd41d25f49..dbb23022b38 100644
--- a/apps/dav/appinfo/install.php
+++ b/apps/dav/appinfo/install.php
@@ -22,5 +22,4 @@
use OCA\Dav\AppInfo\Application;
$app = new Application();
-$app->setupCron();
$app->generateBirthdays();
diff --git a/apps/dav/appinfo/update.php b/apps/dav/appinfo/update.php
index fbd41d25f49..dbb23022b38 100644
--- a/apps/dav/appinfo/update.php
+++ b/apps/dav/appinfo/update.php
@@ -22,5 +22,4 @@
use OCA\Dav\AppInfo\Application;
$app = new Application();
-$app->setupCron();
$app->generateBirthdays();
diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php
index 18f28a916f1..787bcdf469b 100644
--- a/apps/dav/lib/connector/sabre/principal.php
+++ b/apps/dav/lib/connector/sabre/principal.php
@@ -196,6 +196,14 @@ class Principal implements BackendInterface {
* @return string
*/
function findByUri($uri, $principalPrefix) {
+ if (substr($uri, 0, 7) === 'mailto:') {
+ $email = substr($uri, 7);
+ $users = $this->userManager->getByEmail($email);
+ if (count($users) === 1) {
+ return $this->principalPrefix . '/' . $users[0]->getUID();
+ }
+ }
+
return '';
}
diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php
index 73e24c9a292..edaa7ac8552 100644
--- a/apps/dav/lib/server.php
+++ b/apps/dav/lib/server.php
@@ -84,6 +84,9 @@ class Server {
// acl
$acl = new DavAclPlugin();
+ $acl->principalCollectionSet = [
+ 'principals/users', 'principals/groups'
+ ];
$acl->defaultUsernamePath = 'principals/users';
$this->server->addPlugin($acl);
diff --git a/apps/dav/tests/unit/connector/sabre/principal.php b/apps/dav/tests/unit/connector/sabre/principal.php
index 1747885240a..75076e9618b 100644
--- a/apps/dav/tests/unit/connector/sabre/principal.php
+++ b/apps/dav/tests/unit/connector/sabre/principal.php
@@ -255,4 +255,19 @@ class Principal extends TestCase {
public function testSearchPrincipals() {
$this->assertSame([], $this->connector->searchPrincipals('principals/users', []));
}
+
+ public function testFindByUri() {
+ $fooUser = $this->getMockBuilder('\OC\User\User')
+ ->disableOriginalConstructor()->getMock();
+ $fooUser
+ ->expects($this->exactly(1))
+ ->method('getUID')
+ ->will($this->returnValue('foo'));
+
+ $this->userManager->expects($this->once())->method('getByEmail')->willReturn([
+ $fooUser
+ ]);
+ $ret = $this->connector->findByUri('mailto:foo@bar.net', 'principals/users');
+ $this->assertSame('principals/users/foo', $ret);
+ }
}
diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php
index 68098530017..af762845326 100644
--- a/apps/files_sharing/api/share20ocs.php
+++ b/apps/files_sharing/api/share20ocs.php
@@ -28,11 +28,12 @@ use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Files\IRootFolder;
+use OCP\Lock\LockedException;
use OCP\Share;
use OCP\Share\IManager;
-
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\Exceptions\GenericShareException;
+use OCP\Lock\ILockingProvider;
/**
* Class Share20OCS
@@ -205,12 +206,21 @@ class Share20OCS {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
}
+ try {
+ $share->getNode()->lock(ILockingProvider::LOCK_SHARED);
+ } catch (LockedException $e) {
+ return new \OC_OCS_Result(null, 404, 'could not delete share');
+ }
+
if (!$this->canAccessShare($share)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Could not delete share'));
}
$this->shareManager->deleteShare($share);
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
+
return new \OC_OCS_Result();
}
@@ -233,12 +243,18 @@ class Share20OCS {
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
try {
$path = $userFolder->get($path);
- } catch (\OCP\Files\NotFoundException $e) {
+ } catch (NotFoundException $e) {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
}
$share->setNode($path);
+ try {
+ $share->getNode()->lock(ILockingProvider::LOCK_SHARED);
+ } catch (LockedException $e) {
+ return new \OC_OCS_Result(null, 404, 'Could not create share');
+ }
+
// Parse permissions (if available)
$permissions = $this->request->getParam('permissions', null);
if ($permissions === null) {
@@ -248,6 +264,7 @@ class Share20OCS {
}
if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, 'invalid permissions');
}
@@ -275,17 +292,20 @@ class Share20OCS {
if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
// Valid user is required to share
if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid user'));
}
$share->setSharedWith($shareWith);
$share->setPermissions($permissions);
} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
if (!$this->shareManager->allowGroupSharing()) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Group sharing is disabled by the administrator'));
}
// Valid group is required to share
if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid group'));
}
$share->setSharedWith($shareWith);
@@ -293,6 +313,7 @@ class Share20OCS {
} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
//Can we even share links?
if (!$this->shareManager->shareApiAllowLinks()) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Public link sharing is disabled by the administrator'));
}
@@ -302,6 +323,7 @@ class Share20OCS {
*/
$existingShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
if (!empty($existingShares)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result($this->formatShare($existingShares[0]));
}
@@ -309,11 +331,13 @@ class Share20OCS {
if ($publicUpload === 'true') {
// Check if public upload is allowed
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
}
// Public upload can only be set for folders
if ($path instanceof \OCP\Files\File) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Public upload is only possible for publicly shared folders'));
}
@@ -341,18 +365,21 @@ class Share20OCS {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
} catch (\Exception $e) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
}
$share->setSharedWith($shareWith);
$share->setPermissions($permissions);
} else {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Unknown share type'));
}
@@ -363,13 +390,18 @@ class Share20OCS {
$share = $this->shareManager->createShare($share);
} catch (GenericShareException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode();
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, $code, $e->getHint());
}catch (\Exception $e) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $e->getMessage());
}
- $share = $this->formatShare($share);
- return new \OC_OCS_Result($share);
+ $output = $this->formatShare($share);
+
+ $share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+ return new \OC_OCS_Result($output);
}
/**
@@ -454,17 +486,28 @@ class Share20OCS {
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
try {
$path = $userFolder->get($path);
+ $path->lock(ILockingProvider::LOCK_SHARED);
} catch (\OCP\Files\NotFoundException $e) {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
+ } catch (LockedException $e) {
+ return new \OC_OCS_Result(null, 404, $this->l->t('Could not lock path'));
}
}
if ($sharedWithMe === 'true') {
- return $this->getSharedWithMe($path);
+ $result = $this->getSharedWithMe($path);
+ if ($path !== null) {
+ $path->unlock(ILockingProvider::LOCK_SHARED);
+ }
+ return $result;
}
if ($subfiles === 'true') {
- return $this->getSharesInDir($path);
+ $result = $this->getSharesInDir($path);
+ if ($path !== null) {
+ $path->unlock(ILockingProvider::LOCK_SHARED);
+ }
+ return $result;
}
if ($reshares === 'true') {
@@ -494,6 +537,10 @@ class Share20OCS {
}
}
+ if ($path !== null) {
+ $path->unlock(ILockingProvider::LOCK_SHARED);
+ }
+
return new \OC_OCS_Result($formatted);
}
@@ -512,7 +559,10 @@ class Share20OCS {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
}
+ $share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
if (!$this->canAccessShare($share)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
}
@@ -526,6 +576,7 @@ class Share20OCS {
*/
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given');
}
@@ -543,15 +594,18 @@ class Share20OCS {
if ($newPermissions !== null &&
$newPermissions !== \OCP\Constants::PERMISSION_READ &&
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links'));
}
if ($newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
}
if (!($share->getNode() instanceof \OCP\Files\Folder)) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders'));
}
}
@@ -566,6 +620,7 @@ class Share20OCS {
try {
$expireDate = $this->parseDate($expireDate);
} catch (\Exception $e) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $e->getMessage());
}
$share->setExpirationDate($expireDate);
@@ -580,6 +635,7 @@ class Share20OCS {
} else {
// For other shares only permissions is valid.
if ($permissions === null) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Wrong or no update parameter given'));
} else {
$permissions = (int)$permissions;
@@ -599,6 +655,7 @@ class Share20OCS {
}
if ($share->getPermissions() & ~$maxPermissions) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Cannot increase permissions'));
}
}
@@ -608,9 +665,12 @@ class Share20OCS {
try {
$share = $this->shareManager->updateShare($share);
} catch (\Exception $e) {
+ $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $e->getMessage());
}
+ $share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
return new \OC_OCS_Result($this->formatShare($share));
}
diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php
index 56c350aa99a..ffb74da2af7 100644
--- a/apps/files_sharing/tests/api/share20ocstest.php
+++ b/apps/files_sharing/tests/api/share20ocstest.php
@@ -29,6 +29,7 @@ use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Files\IRootFolder;
+use OCP\Lock\LockedException;
/**
* Class Share20OCSTest
@@ -137,8 +138,11 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testDeleteShare() {
+ $node = $this->getMock('\OCP\Files\File');
+
$share = $this->newShare();
- $share->setSharedBy($this->currentUser->getUID());
+ $share->setSharedBy($this->currentUser->getUID())
+ ->setNode($node);
$this->shareManager
->expects($this->once())
->method('getShareById')
@@ -149,10 +153,45 @@ class Share20OCSTest extends \Test\TestCase {
->method('deleteShare')
->with($share);
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $node->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$expected = new \OC_OCS_Result();
$this->assertEquals($expected, $this->ocs->deleteShare(42));
}
+ public function testDeleteShareLocked() {
+ $node = $this->getMock('\OCP\Files\File');
+
+ $share = $this->newShare();
+ $share->setSharedBy($this->currentUser->getUID())
+ ->setNode($node);
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+ $this->shareManager
+ ->expects($this->never())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED)
+ ->will($this->throwException(new LockedException('mypath')));
+ $node->expects($this->never())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+ $expected = new \OC_OCS_Result(null, 404, 'could not delete share');
+ $this->assertEquals($expected, $this->ocs->deleteShare(42));
+ }
+
/*
* FIXME: Enable once we have a federated Share Provider
@@ -526,7 +565,7 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareInvalidPermissions() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->request
@@ -548,6 +587,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-path')
->willReturn($path);
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$expected = new \OC_OCS_Result(null, 404, 'invalid permissions');
$result = $this->ocs->createShare();
@@ -557,7 +600,7 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareUserNoShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->request
@@ -585,6 +628,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-path')
->willReturn($path);
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
$result = $this->ocs->createShare();
@@ -594,7 +641,7 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareUserNoValidShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->request
@@ -625,6 +672,10 @@ class Share20OCSTest extends \Test\TestCase {
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -632,9 +683,8 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareUser() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
- $this->shareManager->method('createShare')->will($this->returnArgument(0));
$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([
@@ -677,15 +727,26 @@ class Share20OCSTest extends \Test\TestCase {
$this->userManager->method('userExists')->with('validUser')->willReturn(true);
- $share->method('setNode')->with($path);
- $share->method('setPermissions')
- ->with(
- \OCP\Constants::PERMISSION_ALL &
- ~\OCP\Constants::PERMISSION_DELETE &
- ~\OCP\Constants::PERMISSION_CREATE);
- $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_USER);
- $share->method('setSharedWith')->with('validUser');
- $share->method('setSharedBy')->with('currentUser');
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $path->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
+ return $share->getNode() === $path &&
+ $share->getPermissions() === (
+ \OCP\Constants::PERMISSION_ALL &
+ ~\OCP\Constants::PERMISSION_DELETE &
+ ~\OCP\Constants::PERMISSION_CREATE
+ ) &&
+ $share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
+ $share->getSharedWith() === 'validUser' &&
+ $share->getSharedBy() === 'currentUser';
+ }))
+ ->will($this->returnArgument(0));
$expected = new \OC_OCS_Result();
$result = $ocs->createShare();
@@ -695,7 +756,7 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareGroupNoValidShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0));
@@ -727,6 +788,10 @@ class Share20OCSTest extends \Test\TestCase {
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -734,9 +799,8 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareGroup() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
- $this->shareManager->method('createShare')->will($this->returnArgument(0));
$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([
@@ -783,11 +847,22 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing')
->willReturn(true);
- $share->method('setNode')->with($path);
- $share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL);
- $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP);
- $share->method('setSharedWith')->with('validGroup');
- $share->method('setSharedBy')->with('currentUser');
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $path->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
+ return $share->getNode() === $path &&
+ $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
+ $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
+ $share->getSharedWith() === 'validGroup' &&
+ $share->getSharedBy() === 'currentUser';
+ }))
+ ->will($this->returnArgument(0));
$expected = new \OC_OCS_Result();
$result = $ocs->createShare();
@@ -797,7 +872,7 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testCreateShareGroupNotAllowed() {
- $share = $this->getMock('\OCP\Share\IShare');
+ $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->request
@@ -832,9 +907,8 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing')
->willReturn(false);
- $share->method('setNode')->with($path);
-
$expected = new \OC_OCS_Result(null, 404, 'Group sharing is disabled by the administrator');
+
$result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -1154,7 +1228,13 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testUpdateShareCantAccess() {
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\Folder');
+ $share = $this->newShare();
+ $share->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@@ -1166,10 +1246,16 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testUpdateNoParametersLink() {
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\Folder');
+ $share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK);
+ ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@@ -1181,10 +1267,16 @@ class Share20OCSTest extends \Test\TestCase {
}
public function testUpdateNoParametersOther() {
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\Folder');
+ $share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_GROUP);
+ ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@@ -1198,13 +1290,22 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareClear() {
$ocs = $this->mockFormatShare();
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\Folder');
+ $share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->setExpirationDate(new \DateTime())
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
+ ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $node->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->request
->method('getParam')
@@ -1364,13 +1465,22 @@ class Share20OCSTest extends \Test\TestCase {
$date = new \DateTime('2000-01-01');
$date->setTime(0,0,0);
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\File');
+ $share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->setExpirationDate($date)
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
+ ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $node->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->request
->method('getParam')
@@ -1398,13 +1508,15 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
$ocs = $this->mockFormatShare();
- $share = \OC::$server->getShareManager()->newShare();
+ $node = $this->getMock('\OCP\Files\File');
+ $share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->setExpirationDate(new \DateTime())
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
+ ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+ ->setNode($node);
$this->request
->method('getParam')
@@ -1412,6 +1524,13 @@ class Share20OCSTest extends \Test\TestCase {
['expireDate', null, '2010-12-23'],
]));
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+ $node->expects($this->once())
+ ->method('unlock')
+ ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$this->shareManager->expects($this->once())->method('updateShare')->with(
diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php
index 08411856e7e..00a362864e5 100644
--- a/apps/provisioning_api/appinfo/routes.php
+++ b/apps/provisioning_api/appinfo/routes.php
@@ -26,10 +26,13 @@
namespace OCA\Provisioning_API\AppInfo;
+use OCA\Provisioning_API\Apps;
+use OCA\Provisioning_API\Groups;
+use OCA\Provisioning_API\Users;
use OCP\API;
// Users
-$users = new \OCA\Provisioning_API\Users(
+$users = new Users(
\OC::$server->getUserManager(),
\OC::$server->getConfig(),
\OC::$server->getGroupManager(),
@@ -41,6 +44,8 @@ API::register('post', '/cloud/users', [$users, 'addUser'], 'provisioning_api', A
API::register('get', '/cloud/users/{userid}', [$users, 'getUser'], 'provisioning_api', API::USER_AUTH);
API::register('put', '/cloud/users/{userid}', [$users, 'editUser'], 'provisioning_api', API::USER_AUTH);
API::register('delete', '/cloud/users/{userid}', [$users, 'deleteUser'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('put', '/cloud/users/{userid}/enable', [$users, 'enableUser'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('put', '/cloud/users/{userid}/disable', [$users, 'disableUser'], 'provisioning_api', API::SUBADMIN_AUTH);
API::register('get', '/cloud/users/{userid}/groups', [$users, 'getUsersGroups'], 'provisioning_api', API::USER_AUTH);
API::register('post', '/cloud/users/{userid}/groups', [$users, 'addToGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
API::register('delete', '/cloud/users/{userid}/groups', [$users, 'removeFromGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
@@ -49,7 +54,7 @@ API::register('delete', '/cloud/users/{userid}/subadmins', [$users, 'removeSubAd
API::register('get', '/cloud/users/{userid}/subadmins', [$users, 'getUserSubAdminGroups'], 'provisioning_api', API::ADMIN_AUTH);
// Groups
-$groups = new \OCA\Provisioning_API\Groups(
+$groups = new Groups(
\OC::$server->getGroupManager(),
\OC::$server->getUserSession(),
\OC::$server->getRequest()
@@ -61,7 +66,7 @@ API::register('delete', '/cloud/groups/{groupid}', [$groups, 'deleteGroup'], 'pr
API::register('get', '/cloud/groups/{groupid}/subadmins', [$groups, 'getSubAdminsOfGroup'], 'provisioning_api', API::ADMIN_AUTH);
// Apps
-$apps = new \OCA\Provisioning_API\Apps(
+$apps = new Apps(
\OC::$server->getAppManager(),
\OC::$server->getOcsClient()
);
diff --git a/apps/provisioning_api/lib/users.php b/apps/provisioning_api/lib/users.php
index 68c89e41f6f..2749372c393 100644
--- a/apps/provisioning_api/lib/users.php
+++ b/apps/provisioning_api/lib/users.php
@@ -31,32 +31,36 @@ namespace OCA\Provisioning_API;
use \OC_OCS_Result;
use \OC_Helper;
use OCP\Files\NotFoundException;
+use OCP\IConfig;
+use OCP\IGroupManager;
use OCP\ILogger;
+use OCP\IUserManager;
+use OCP\IUserSession;
class Users {
- /** @var \OCP\IUserManager */
+ /** @var IUserManager */
private $userManager;
- /** @var \OCP\IConfig */
+ /** @var IConfig */
private $config;
- /** @var \OCP\IGroupManager */
+ /** @var IGroupManager */
private $groupManager;
- /** @var \OCP\IUserSession */
+ /** @var IUserSession */
private $userSession;
/** @var ILogger */
private $logger;
/**
- * @param \OCP\IUserManager $userManager
- * @param \OCP\IConfig $config
- * @param \OCP\IGroupManager $groupManager
- * @param \OCP\IUserSession $userSession
+ * @param IUserManager $userManager
+ * @param IConfig $config
+ * @param IGroupManager $groupManager
+ * @param IUserSession $userSession
* @param ILogger $logger
*/
- public function __construct(\OCP\IUserManager $userManager,
- \OCP\IConfig $config,
- \OCP\IGroupManager $groupManager,
- \OCP\IUserSession $userSession,
+ public function __construct(IUserManager $userManager,
+ IConfig $config,
+ IGroupManager $groupManager,
+ IUserSession $userSession,
ILogger $logger) {
$this->userManager = $userManager;
$this->config = $config;
@@ -333,6 +337,50 @@ class Users {
* @param array $parameters
* @return OC_OCS_Result
*/
+ public function disableUser($parameters) {
+ return $this->setEnabled($parameters, false);
+ }
+
+ /**
+ * @param array $parameters
+ * @return OC_OCS_Result
+ */
+ public function enableUser($parameters) {
+ return $this->setEnabled($parameters, true);
+ }
+
+ /**
+ * @param array $parameters
+ * @param bool $value
+ * @return OC_OCS_Result
+ */
+ private function setEnabled($parameters, $value) {
+ // Check if user is logged in
+ $currentLoggedInUser = $this->userSession->getUser();
+ if ($currentLoggedInUser === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
+ $targetUser = $this->userManager->get($parameters['userid']);
+ if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
+ return new OC_OCS_Result(null, 101);
+ }
+
+ // If not permitted
+ $subAdminManager = $this->groupManager->getSubAdmin();
+ if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
+ return new OC_OCS_Result(null, 997);
+ }
+
+ // enable/disable the user now
+ $targetUser->setEnabled($value);
+ return new OC_OCS_Result(null, 100);
+ }
+
+ /**
+ * @param array $parameters
+ * @return OC_OCS_Result
+ */
public function getUsersGroups($parameters) {
// Check if user is logged in
$loggedInUser = $this->userSession->getUser();
diff --git a/apps/provisioning_api/tests/userstest.php b/apps/provisioning_api/tests/userstest.php
index 020071bcfa1..8f463ec8b88 100644
--- a/apps/provisioning_api/tests/userstest.php
+++ b/apps/provisioning_api/tests/userstest.php
@@ -58,8 +58,8 @@ class UsersTest extends OriginalTest {
parent::tearDown();
}
- protected function setup() {
- parent::setup();
+ protected function setUp() {
+ parent::setUp();
$this->userManager = $this->getMock('\OCP\IUserManager');
$this->config = $this->getMock('\OCP\IConfig');
@@ -540,7 +540,7 @@ class UsersTest extends OriginalTest {
->expects($this->once())
->method('isSubAdminOfGroup')
->with($loggedInUser, $existingGroup)
- ->wilLReturn(false);
+ ->willReturn(false);
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
@@ -642,7 +642,7 @@ class UsersTest extends OriginalTest {
[$loggedInUser, $existingGroup1],
[$loggedInUser, $existingGroup2]
)
- ->wilLReturn(true);
+ ->willReturn(true);
$expected = new \OC_OCS_Result(null, 100);
@@ -2295,4 +2295,60 @@ class UsersTest extends OriginalTest {
$expected = new \OC_OCS_Result(null, 102, 'Unknown error occurred');
$this->assertEquals($expected, $this->api->getUserSubAdminGroups(['userid' => 'RequestedUser']));
}
+
+ public function testEnableUser() {
+ $targetUser = $this->getMock('\OCP\IUser');
+ $targetUser->expects($this->once())
+ ->method('setEnabled')
+ ->with(true);
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('RequestedUser')
+ ->will($this->returnValue($targetUser));
+ $loggedInUser = $this->getMock('\OCP\IUser');
+ $loggedInUser
+ ->expects($this->exactly(2))
+ ->method('getUID')
+ ->will($this->returnValue('admin'));
+ $this->userSession
+ ->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($loggedInUser));
+ $this->groupManager
+ ->expects($this->once())
+ ->method('isAdmin')
+ ->will($this->returnValue(true));
+
+ $expected = new \OC_OCS_Result(null, 100);
+ $this->assertEquals($expected, $this->api->enableUser(['userid' => 'RequestedUser']));
+ }
+
+ public function testDisableUser() {
+ $targetUser = $this->getMock('\OCP\IUser');
+ $targetUser->expects($this->once())
+ ->method('setEnabled')
+ ->with(false);
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('RequestedUser')
+ ->will($this->returnValue($targetUser));
+ $loggedInUser = $this->getMock('\OCP\IUser');
+ $loggedInUser
+ ->expects($this->exactly(2))
+ ->method('getUID')
+ ->will($this->returnValue('admin'));
+ $this->userSession
+ ->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($loggedInUser));
+ $this->groupManager
+ ->expects($this->once())
+ ->method('isAdmin')
+ ->will($this->returnValue(true));
+
+ $expected = new \OC_OCS_Result(null, 100);
+ $this->assertEquals($expected, $this->api->disableUser(['userid' => 'RequestedUser']));
+ }
}
diff --git a/build/integration/features/bootstrap/Provisioning.php b/build/integration/features/bootstrap/Provisioning.php
index feeb850ae7d..6cf57514483 100644
--- a/build/integration/features/bootstrap/Provisioning.php
+++ b/build/integration/features/bootstrap/Provisioning.php
@@ -35,7 +35,6 @@ trait Provisioning {
}
$this->userExists($user);
PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
-
}
/**
@@ -231,6 +230,20 @@ trait Provisioning {
}
/**
+ * @When /^assure user "([^"]*)" is disabled$/
+ */
+ public function assureUserIsDisabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+ }
+
+ /**
* @When /^Deleting the user "([^"]*)"$/
* @param string $user
*/
@@ -364,6 +377,25 @@ trait Provisioning {
}
/**
+ * @Given /^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function assureUserIsSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+ $options['body'] = [
+ 'groupid' => $group
+ ];
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
* @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/
* @param string $user
* @param string $group
@@ -529,6 +561,38 @@ trait Provisioning {
}
/**
+ * @Then /^user "([^"]*)" is disabled$/
+ * @param string $user
+ */
+ public function userIsDisabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals("false", $this->response->xml()->data[0]->enabled);
+ }
+
+ /**
+ * @Then /^user "([^"]*)" is enabled$/
+ * @param string $user
+ */
+ public function userIsEnabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals("true", $this->response->xml()->data[0]->enabled);
+ }
+
+ /**
* @Given user :user has a quota of :quota
* @param string $user
* @param string $quota
@@ -588,4 +652,5 @@ trait Provisioning {
}
$this->usingServer($previousServer);
}
+
}
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index 79c447ac573..cd9584ad186 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -424,5 +424,15 @@ trait WebDav {
}
+ /**
+ * @Given /^Downloading file "([^"]*)" as "([^"]*)"$/
+ */
+ public function downloadingFileAs($fileName, $user) {
+ try {
+ $this->response = $this->makeDavRequest($user, 'GET', $fileName, []);
+ } catch (\GuzzleHttp\Exception\ServerException $ex) {
+ $this->response = $ex->getResponse();
+ }
+ }
}
diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature
index 8c32c04523c..d44903c2743 100644
--- a/build/integration/features/provisioning-v1.feature
+++ b/build/integration/features/provisioning-v1.feature
@@ -315,3 +315,197 @@ Feature: provisioning
Then the OCS status code should be "100"
And the HTTP status code should be "200"
And app "files_external" is disabled
+
+ Scenario: disable an user
+ Given As an "admin"
+ And user "user1" exists
+ When sending "PUT" to "/cloud/users/user1/disable"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And user "user1" is disabled
+
+ Scenario: enable an user
+ Given As an "admin"
+ And user "user1" exists
+ And assure user "user1" is disabled
+ When sending "PUT" to "/cloud/users/user1/enable"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And user "user1" is enabled
+
+ Scenario: Subadmin should be able to enable or disable an user in their group
+ Given As an "admin"
+ And user "subadmin" exists
+ And user "user1" exists
+ And group "new-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And user "user1" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And As an "subadmin"
+ When sending "PUT" to "/cloud/users/user1/disable"
+ Then the OCS status code should be "100"
+ Then the HTTP status code should be "200"
+ And As an "admin"
+ And user "user1" is disabled
+
+ Scenario: Subadmin should not be able to enable or disable an user not in their group
+ Given As an "admin"
+ And user "subadmin" exists
+ And user "user1" exists
+ And group "new-group" exists
+ And group "another-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And user "user1" belongs to group "another-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And As an "subadmin"
+ When sending "PUT" to "/cloud/users/user1/disable"
+ Then the OCS status code should be "997"
+ Then the HTTP status code should be "401"
+ And As an "admin"
+ And user "user1" is enabled
+
+ Scenario: Subadmins should not be able to disable users that have admin permissions in their group
+ Given As an "admin"
+ And user "another-admin" exists
+ And user "subadmin" exists
+ And group "new-group" exists
+ And user "another-admin" belongs to group "admin"
+ And user "subadmin" belongs to group "new-group"
+ And user "another-admin" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And As an "subadmin"
+ When sending "PUT" to "/cloud/users/another-admin/disable"
+ Then the OCS status code should be "997"
+ Then the HTTP status code should be "401"
+ And As an "admin"
+ And user "another-admin" is enabled
+
+ Scenario: Admin can disable another admin user
+ Given As an "admin"
+ And user "another-admin" exists
+ And user "another-admin" belongs to group "admin"
+ When sending "PUT" to "/cloud/users/another-admin/disable"
+ Then the OCS status code should be "100"
+ Then the HTTP status code should be "200"
+ And user "another-admin" is disabled
+
+ Scenario: Admin can enable another admin user
+ Given As an "admin"
+ And user "another-admin" exists
+ And user "another-admin" belongs to group "admin"
+ And assure user "another-admin" is disabled
+ When sending "PUT" to "/cloud/users/another-admin/enable"
+ Then the OCS status code should be "100"
+ Then the HTTP status code should be "200"
+ And user "another-admin" is enabled
+
+ Scenario: Admin can disable subadmins in the same group
+ Given As an "admin"
+ And user "subadmin" exists
+ And group "new-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And user "admin" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ When sending "PUT" to "/cloud/users/subadmin/disable"
+ Then the OCS status code should be "100"
+ Then the HTTP status code should be "200"
+ And user "subadmin" is disabled
+
+ Scenario: Admin can enable subadmins in the same group
+ Given As an "admin"
+ And user "subadmin" exists
+ And group "new-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And user "admin" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And assure user "another-admin" is disabled
+ When sending "PUT" to "/cloud/users/subadmin/disable"
+ Then the OCS status code should be "100"
+ Then the HTTP status code should be "200"
+ And user "subadmin" is disabled
+
+ Scenario: Admin user cannot disable himself
+ Given As an "admin"
+ And user "another-admin" exists
+ And user "another-admin" belongs to group "admin"
+ And As an "another-admin"
+ When sending "PUT" to "/cloud/users/another-admin/disable"
+ Then the OCS status code should be "101"
+ And the HTTP status code should be "200"
+ And As an "admin"
+ And user "another-admin" is enabled
+
+ Scenario:Admin user cannot enable himself
+ Given As an "admin"
+ And user "another-admin" exists
+ And user "another-admin" belongs to group "admin"
+ And assure user "another-admin" is disabled
+ And As an "another-admin"
+ When sending "PUT" to "/cloud/users/another-admin/enable"
+ And As an "admin"
+ Then user "another-admin" is disabled
+
+ Scenario: disable an user with a regular user
+ Given As an "admin"
+ And user "user1" exists
+ And user "user2" exists
+ And As an "user1"
+ When sending "PUT" to "/cloud/users/user2/disable"
+ Then the OCS status code should be "997"
+ And the HTTP status code should be "401"
+ And As an "admin"
+ And user "user2" is enabled
+
+ Scenario: enable an user with a regular user
+ Given As an "admin"
+ And user "user1" exists
+ And user "user2" exists
+ And assure user "user2" is disabled
+ And As an "user1"
+ When sending "PUT" to "/cloud/users/user2/enable"
+ Then the OCS status code should be "997"
+ And the HTTP status code should be "401"
+ And As an "admin"
+ And user "user2" is disabled
+
+ Scenario: Subadmin should not be able to disable himself
+ Given As an "admin"
+ And user "subadmin" exists
+ And group "new-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And As an "subadmin"
+ When sending "PUT" to "/cloud/users/subadmin/disable"
+ Then the OCS status code should be "101"
+ Then the HTTP status code should be "200"
+ And As an "admin"
+ And user "subadmin" is enabled
+
+ Scenario: Subadmin should not be able to enable himself
+ Given As an "admin"
+ And user "subadmin" exists
+ And group "new-group" exists
+ And user "subadmin" belongs to group "new-group"
+ And Assure user "subadmin" is subadmin of group "new-group"
+ And assure user "subadmin" is disabled
+ And As an "subadmin"
+ When sending "PUT" to "/cloud/users/subadmin/enabled"
+ And As an "admin"
+ And user "subadmin" is disabled
+
+ Scenario: Making a web request with an enabled user
+ Given As an "admin"
+ And user "user0" exists
+ And As an "user0"
+ When sending "GET" to "/index.php/apps/files"
+ Then the HTTP status code should be "200"
+
+ Scenario: Making a web request with a disabled user
+ Given As an "admin"
+ And user "user0" exists
+ And assure user "user0" is disabled
+ And As an "user0"
+ When sending "GET" to "/index.php/apps/files"
+ Then the OCS status code should be "999"
+ And the HTTP status code should be "200"
+
diff --git a/build/integration/features/sharing-v1.feature b/build/integration/features/sharing-v1.feature
index d67afede953..79d7617f024 100644
--- a/build/integration/features/sharing-v1.feature
+++ b/build/integration/features/sharing-v1.feature
@@ -696,3 +696,16 @@ Feature: sharing
Then user "user2" should see following elements
| /foo/ |
| /foo%20(2)/ |
+
+ Scenario: Creating a new share with a disabled user
+ Given As an "admin"
+ And user "user0" exists
+ And user "user1" exists
+ And assure user "user0" is disabled
+ And As an "user0"
+ When sending "POST" to "/apps/files_sharing/api/v1/shares" with
+ | path | welcome.txt |
+ | shareWith | user1 |
+ | shareType | 0 |
+ Then the OCS status code should be "997"
+ And the HTTP status code should be "401"
diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature
index abdc63935e9..f4d40615fa7 100644
--- a/build/integration/features/webdav-related.feature
+++ b/build/integration/features/webdav-related.feature
@@ -286,3 +286,11 @@ Feature: webdav-related
When As an "user0"
And Downloading file "/files/user0/myChunkedFile.txt"
Then Downloaded content should be "AAAAABBBBBCCCCC"
+
+ Scenario: A disabled user cannot use webdav
+ Given user "userToBeDisabled" exists
+ And As an "admin"
+ And assure user "userToBeDisabled" is disabled
+ When Downloading file "/welcome.txt" as "userToBeDisabled"
+ Then the HTTP status code should be "503"
+
diff --git a/core/Command/Log/Manage.php b/core/Command/Log/Manage.php
index 1d65d7ed0d8..aeaaca8aa0e 100644
--- a/core/Command/Log/Manage.php
+++ b/core/Command/Log/Manage.php
@@ -115,7 +115,7 @@ class Manage extends Command {
* @throws \InvalidArgumentException
*/
protected function validateBackend($backend) {
- if (!class_exists('OC_Log_'.$backend)) {
+ if (!class_exists('OC\\Log\\'.ucfirst($backend))) {
throw new \InvalidArgumentException('Invalid backend');
}
}
diff --git a/core/Command/User/Disable.php b/core/Command/User/Disable.php
new file mode 100644
index 00000000000..018f11190d6
--- /dev/null
+++ b/core/Command/User/Disable.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\User;
+
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+
+class Disable extends Command {
+ /** @var IUserManager */
+ protected $userManager;
+
+ /**
+ * @param IUserManager $userManager
+ */
+ public function __construct(IUserManager $userManager) {
+ $this->userManager = $userManager;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('user:disable')
+ ->setDescription('disables the specified user')
+ ->addArgument(
+ 'uid',
+ InputArgument::REQUIRED,
+ 'the username'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $user = $this->userManager->get($input->getArgument('uid'));
+ if (is_null($user)) {
+ $output->writeln('<error>User does not exist</error>');
+ return;
+ }
+
+ $user->setEnabled(false);
+ $output->writeln('<info>The specified user is disabled</info>');
+ }
+}
diff --git a/core/Command/User/Enable.php b/core/Command/User/Enable.php
new file mode 100644
index 00000000000..ffe2e40d654
--- /dev/null
+++ b/core/Command/User/Enable.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\User;
+
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+
+class Enable extends Command {
+ /** @var IUserManager */
+ protected $userManager;
+
+ /**
+ * @param IUserManager $userManager
+ */
+ public function __construct(IUserManager $userManager) {
+ $this->userManager = $userManager;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('user:enable')
+ ->setDescription('enables the specified user')
+ ->addArgument(
+ 'uid',
+ InputArgument::REQUIRED,
+ 'the username'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $user = $this->userManager->get($input->getArgument('uid'));
+ if (is_null($user)) {
+ $output->writeln('<error>User does not exist</error>');
+ return;
+ }
+
+ $user->setEnabled(true);
+ $output->writeln('<info>The specified user is enabled</info>');
+ }
+}
diff --git a/core/register_command.php b/core/register_command.php
index 798497d97d2..3dab37ce5a6 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -121,6 +121,8 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
$application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
+ $application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
+ $application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
diff --git a/core/templates/login.php b/core/templates/login.php
index 8405bac6890..86c186928cc 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -40,11 +40,11 @@ script('core', [
</div>
<p class="grouptop">
<input type="text" name="user" id="user"
- placeholder="<?php p($l->t('Username')); ?>"
+ placeholder="<?php p($l->t('Username or email')); ?>"
value="<?php p($_['loginName']); ?>"
<?php p($_['user_autofocus'] ? 'autofocus' : ''); ?>
autocomplete="on" autocapitalize="off" autocorrect="off" required>
- <label for="user" class="infield"><?php p($l->t('Username')); ?></label>
+ <label for="user" class="infield"><?php p($l->t('Username or email')); ?></label>
</p>
<p class="groupbottom">
diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php
index 21422d40603..e9456550206 100644
--- a/lib/private/App/InfoParser.php
+++ b/lib/private/App/InfoParser.php
@@ -89,6 +89,9 @@ class InfoParser {
if (!array_key_exists('uninstall', $array['repair-steps'])) {
$array['repair-steps']['uninstall'] = [];
}
+ if (!array_key_exists('background-jobs', $array)) {
+ $array['background-jobs'] = [];
+ }
if (array_key_exists('documentation', $array) && is_array($array['documentation'])) {
foreach ($array['documentation'] as $key => $url) {
@@ -128,6 +131,9 @@ class InfoParser {
if (isset($array['repair-steps']['uninstall']['step']) && is_array($array['repair-steps']['uninstall']['step'])) {
$array['repair-steps']['uninstall'] = $array['repair-steps']['uninstall']['step'];
}
+ if (isset($array['background-jobs']['job']) && is_array($array['background-jobs']['job'])) {
+ $array['background-jobs'] = $array['background-jobs']['job'];
+ }
return $array;
}
@@ -147,10 +153,7 @@ class InfoParser {
if (!isset($array[$element])) {
$array[$element] = "";
}
- /**
- * @var \SimpleXMLElement $node
- */
-
+ /** @var \SimpleXMLElement $node */
// Has attributes
if ($attributes = $node->attributes()) {
$data = [
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 8ecc92e134b..edc6306b8f1 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -133,6 +133,8 @@ class Installer {
}
}
+ \OC_App::setupBackgroundJobs($info['background-jobs']);
+
//run appinfo/install.php
if((!isset($data['noinstall']) or $data['noinstall']==false)) {
self::includeAppScript($basedir . '/appinfo/install.php');
@@ -569,6 +571,7 @@ class Installer {
if (is_null($info)) {
return false;
}
+ \OC_App::setupBackgroundJobs($info['background-jobs']);
OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php
index 1886fbea082..ff9f99a9630 100644
--- a/lib/private/Lock/AbstractLockingProvider.php
+++ b/lib/private/Lock/AbstractLockingProvider.php
@@ -77,6 +77,9 @@ abstract class AbstractLockingProvider implements ILockingProvider {
if ($type === self::LOCK_SHARED) {
if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
$this->acquiredLocks['shared'][$path]--;
+ if ($this->acquiredLocks['shared'][$path] === 0) {
+ unset($this->acquiredLocks['shared'][$path]);
+ }
}
} else if ($type === self::LOCK_EXCLUSIVE) {
unset($this->acquiredLocks['exclusive'][$path]);
diff --git a/lib/private/Log.php b/lib/private/Log.php
index d82346bbcf0..9248070c067 100644
--- a/lib/private/Log.php
+++ b/lib/private/Log.php
@@ -73,7 +73,7 @@ class Log implements ILogger {
// FIXME: Add this for backwards compatibility, should be fixed at some point probably
if($logger === null) {
- $this->logger = 'OC_Log_'.ucfirst($this->config->getValue('log_type', 'owncloud'));
+ $this->logger = 'OC\\Log\\'.ucfirst($this->config->getValue('log_type', 'owncloud'));
call_user_func(array($this->logger, 'init'));
} else {
$this->logger = $logger;
diff --git a/lib/private/log/errorhandler.php b/lib/private/Log/ErrorHandler.php
index 8899bcfcb03..8899bcfcb03 100644
--- a/lib/private/log/errorhandler.php
+++ b/lib/private/Log/ErrorHandler.php
diff --git a/lib/private/log/errorlog.php b/lib/private/Log/Errorlog.php
index ad3605136d0..37498c36aba 100644
--- a/lib/private/log/errorlog.php
+++ b/lib/private/Log/Errorlog.php
@@ -23,7 +23,9 @@
* THE SOFTWARE.
*/
-class OC_Log_Errorlog {
+namespace OC\Log;
+
+class Errorlog {
/**
diff --git a/lib/private/log/owncloud.php b/lib/private/Log/Owncloud.php
index 9c106299e4c..13997a0d552 100644
--- a/lib/private/log/owncloud.php
+++ b/lib/private/Log/Owncloud.php
@@ -27,13 +27,15 @@
*
*/
+namespace OC\Log;
+
/**
* logging utilities
*
* Log is saved at data/owncloud.log (on default)
*/
-class OC_Log_Owncloud {
+class Owncloud {
static protected $logFile;
/**
@@ -41,7 +43,7 @@ class OC_Log_Owncloud {
*/
public static function init() {
$systemConfig = \OC::$server->getSystemConfig();
- $defaultLogFile = $systemConfig->getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log';
+ $defaultLogFile = $systemConfig->getValue("datadirectory", \OC::$SERVERROOT.'/data').'/owncloud.log';
self::$logFile = $systemConfig->getValue("logfile", $defaultLogFile);
/**
@@ -72,13 +74,13 @@ class OC_Log_Owncloud {
$format = $config->getValue('logdateformat', 'c');
$logTimeZone = $config->getValue( "logtimezone", 'UTC' );
try {
- $timezone = new DateTimeZone($logTimeZone);
- } catch (Exception $e) {
- $timezone = new DateTimeZone('UTC');
+ $timezone = new \DateTimeZone($logTimeZone);
+ } catch (\Exception $e) {
+ $timezone = new \DateTimeZone('UTC');
}
- $time = DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", ""));
+ $time = \DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", ""));
if ($time === false) {
- $time = new DateTime(null, $timezone);
+ $time = new \DateTime(null, $timezone);
} else {
// apply timezone if $time is created from UNIX timestamp
$time->setTimezone($timezone);
diff --git a/lib/private/log/rotate.php b/lib/private/Log/Rotate.php
index 458661c82d0..458661c82d0 100644
--- a/lib/private/log/rotate.php
+++ b/lib/private/Log/Rotate.php
diff --git a/lib/private/log/syslog.php b/lib/private/Log/Syslog.php
index 96cf463d042..115103f26d6 100644
--- a/lib/private/log/syslog.php
+++ b/lib/private/Log/Syslog.php
@@ -21,7 +21,9 @@
*
*/
-class OC_Log_Syslog {
+namespace OC\Log;
+
+class Syslog {
static protected $levels = array(
\OCP\Util::DEBUG => LOG_DEBUG,
\OCP\Util::INFO => LOG_INFO,
diff --git a/lib/private/Server.php b/lib/private/Server.php
index a98ddc36b58..bbe6b88876f 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -329,7 +329,7 @@ class Server extends ServerContainer implements IServerContainer {
});
$this->registerService('Logger', function (Server $c) {
$logClass = $c->query('AllConfig')->getSystemValue('log_type', 'owncloud');
- $logger = 'OC_Log_' . ucfirst($logClass);
+ $logger = 'OC\\Log\\' . ucfirst($logClass);
call_user_func(array($logger, 'init'));
return new Log($logger);
@@ -837,8 +837,7 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * For internal use only
- *
+ * @internal For internal use only
* @return \OC\SystemConfig
*/
public function getSystemConfig() {
@@ -1180,7 +1179,7 @@ class Server extends ServerContainer implements IServerContainer {
return $this->query('MountManager');
}
- /*
+ /**
* Get the MimeTypeDetector
*
* @return \OCP\Files\IMimeTypeDetector
diff --git a/lib/private/share/constants.php b/lib/private/Share/Constants.php
index e60eb98832b..e60eb98832b 100644
--- a/lib/private/share/constants.php
+++ b/lib/private/Share/Constants.php
diff --git a/lib/private/share/helper.php b/lib/private/Share/Helper.php
index f9581e48e62..f9581e48e62 100644
--- a/lib/private/share/helper.php
+++ b/lib/private/Share/Helper.php
diff --git a/lib/private/share/mailnotifications.php b/lib/private/Share/MailNotifications.php
index f71651e71fc..f71651e71fc 100644
--- a/lib/private/share/mailnotifications.php
+++ b/lib/private/Share/MailNotifications.php
diff --git a/lib/private/share/searchresultsorter.php b/lib/private/Share/SearchResultSorter.php
index 6d5542146e7..6d5542146e7 100644
--- a/lib/private/share/searchresultsorter.php
+++ b/lib/private/Share/SearchResultSorter.php
diff --git a/lib/private/share/share.php b/lib/private/Share/Share.php
index 5b61f418a4d..5b61f418a4d 100644
--- a/lib/private/share/share.php
+++ b/lib/private/Share/Share.php
diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php
index bab879c95f8..702b9df1927 100644
--- a/lib/private/legacy/api.php
+++ b/lib/private/legacy/api.php
@@ -356,7 +356,11 @@ class OC_API {
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) ) {
$authUser = $_SERVER['PHP_AUTH_USER'];
$authPw = $_SERVER['PHP_AUTH_PW'];
- $return = OC_User::login($authUser, $authPw);
+ try {
+ $return = OC_User::login($authUser, $authPw);
+ } catch (\OC\User\LoginException $e) {
+ return false;
+ }
if ($return === true) {
self::$logoutRequired = true;
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index fe590e4159e..dab4c1a70c7 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -1190,6 +1190,7 @@ class OC_App {
self::loadApp($appId, false);
include $appPath . '/appinfo/update.php';
}
+ self::setupBackgroundJobs($appData['background-jobs']);
//set remote/public handlers
if (array_key_exists('ocsid', $appData)) {
@@ -1240,6 +1241,13 @@ class OC_App {
$r->run();
}
+ public static function setupBackgroundJobs(array $jobs) {
+ $queue = \OC::$server->getJobList();
+ foreach ($jobs as $job) {
+ $queue->add($job);
+ }
+ }
+
/**
* @param string $appId
* @param string[] $steps
diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php
index 11c35daa0de..18a4c369d5e 100644
--- a/lib/private/legacy/user.php
+++ b/lib/private/legacy/user.php
@@ -63,8 +63,6 @@ class OC_User {
return OC::$server->getUserSession();
}
- private static $_backends = array();
-
private static $_usedBackends = array();
private static $_setupedBackends = array();
@@ -105,7 +103,7 @@ class OC_User {
break;
default:
\OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', \OCP\Util::DEBUG);
- $className = 'OC_USER_' . strToUpper($backend);
+ $className = 'OC_USER_' . strtoupper($backend);
self::$_usedBackends[$backend] = new $className();
\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
break;
@@ -152,14 +150,22 @@ class OC_User {
/**
* Try to login a user
*
- * @param string $loginname The login name of the user to log in
+ * @param string $loginName The login name of the user to log in
* @param string $password The password of the user
* @return boolean|null
*
* Log in a user and regenerate a new session - if the password is ok
*/
- public static function login($loginname, $password) {
- $result = self::getUserSession()->login($loginname, $password);
+ public static function login($loginName, $password) {
+
+ $result = self::getUserSession()->login($loginName, $password);
+ if (!$result) {
+ $users = \OC::$server->getUserManager()->getByEmail($loginName);
+ // we only allow login by email if unique
+ if (count($users) === 1) {
+ $result = self::getUserSession()->login($users[0]->getUID(), $password);
+ }
+ }
if ($result) {
// Refresh the token
\OC::$server->getCsrfTokenManager()->refreshToken();
@@ -175,6 +181,7 @@ class OC_User {
/**
* Try to login a user using the magic cookie (remember login)
*
+ * @deprecated use \OCP\IUserSession::loginWithCookie()
* @param string $uid The username of the user to log in
* @param string $token
* @return bool
@@ -241,6 +248,8 @@ class OC_User {
/**
* Sets user id for session and triggers emit
+ *
+ * @param string $uid
*/
public static function setUserId($uid) {
$userSession = \OC::$server->getUserSession();
@@ -296,14 +305,11 @@ class OC_User {
/**
* Check if the user is logged in, considers also the HTTP basic credentials
*
+ * @deprecated use \OC::$server->getUserSession()->isLoggedIn()
* @return bool
*/
public static function isLoggedIn() {
- if (\OC::$server->getSession()->get('user_id') !== null && self::$incognitoMode === false) {
- return self::userExists(\OC::$server->getSession()->get('user_id'));
- }
-
- return false;
+ return \OC::$server->getUserSession()->isLoggedIn();
}
/**
diff --git a/lib/private/user/database.php b/lib/private/user/database.php
index 22a05090b96..fd273055ae1 100644
--- a/lib/private/user/database.php
+++ b/lib/private/user/database.php
@@ -48,11 +48,21 @@
*
*/
+use OC\Cache\CappedMemoryCache;
+
/**
* Class for user management in a SQL Database (e.g. MySQL, SQLite)
*/
class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
- private $cache = array();
+ /** @var CappedMemoryCache */
+ private $cache;
+
+ /**
+ * OC_User_Database constructor.
+ */
+ public function __construct() {
+ $this->cache = new CappedMemoryCache();
+ }
/**
* Create a new user
diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php
index 4371be134aa..37a3e5ba134 100644
--- a/lib/private/user/manager.php
+++ b/lib/private/user/manager.php
@@ -33,6 +33,7 @@
namespace OC\User;
use OC\Hooks\PublicEmitter;
+use OCP\IUser;
use OCP\IUserBackend;
use OCP\IUserManager;
use OCP\IConfig;
@@ -354,4 +355,17 @@ class Manager extends PublicEmitter implements IUserManager {
} while (count($users) >= $limit);
}
}
+
+ /**
+ * @param string $email
+ * @return IUser[]
+ * @since 9.1.0
+ */
+ public function getByEmail($email) {
+ $userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
+
+ return array_map(function($uid) {
+ return $this->get($uid);
+ }, $userIds);
+ }
}
diff --git a/lib/private/user/session.php b/lib/private/user/session.php
index 5402c5cf74f..c7f8a6920de 100644
--- a/lib/private/user/session.php
+++ b/lib/private/user/session.php
@@ -32,6 +32,8 @@
namespace OC\User;
use OC\Hooks\Emitter;
+use OCP\ISession;
+use OCP\IUserManager;
use OCP\IUserSession;
/**
@@ -53,26 +55,20 @@ use OCP\IUserSession;
* @package OC\User
*/
class Session implements IUserSession, Emitter {
- /**
- * @var \OC\User\Manager $manager
- */
+ /** @var \OC\User\Manager $manager */
private $manager;
- /**
- * @var \OC\Session\Session $session
- */
+ /** @var \OC\Session\Session $session */
private $session;
- /**
- * @var \OC\User\User $activeUser
- */
+ /** @var \OC\User\User $activeUser */
protected $activeUser;
/**
- * @param \OCP\IUserManager $manager
- * @param \OCP\ISession $session
+ * @param IUserManager $manager
+ * @param ISession $session
*/
- public function __construct(\OCP\IUserManager $manager, \OCP\ISession $session) {
+ public function __construct(IUserManager $manager, ISession $session) {
$this->manager = $manager;
$this->session = $session;
}
@@ -107,7 +103,7 @@ class Session implements IUserSession, Emitter {
/**
* get the session object
*
- * @return \OCP\ISession
+ * @return ISession
*/
public function getSession() {
return $this->session;
@@ -116,10 +112,10 @@ class Session implements IUserSession, Emitter {
/**
* set the session object
*
- * @param \OCP\ISession $session
+ * @param ISession $session
*/
- public function setSession(\OCP\ISession $session) {
- if ($this->session instanceof \OCP\ISession) {
+ public function setSession(ISession $session) {
+ if ($this->session instanceof ISession) {
$this->session->close();
}
$this->session = $session;
@@ -170,7 +166,12 @@ class Session implements IUserSession, Emitter {
* @return bool if logged in
*/
public function isLoggedIn() {
- return $this->getUser() !== null;
+ $user = $this->getUser();
+ if (is_null($user)) {
+ return false;
+ }
+
+ return $user->isEnabled();
}
/**
@@ -226,15 +227,18 @@ class Session implements IUserSession, Emitter {
if ($this->isLoggedIn()) {
return true;
} else {
- throw new LoginException('Login canceled by app');
+ // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
+ $message = \OC::$server->getL10N('lib')->t('Login canceled by app');
+ throw new LoginException($message);
}
} else {
- return false;
+ // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
+ $message = \OC::$server->getL10N('lib')->t('User disabled');
+ throw new LoginException($message);
}
}
- } else {
- return false;
}
+ return false;
}
/**
diff --git a/lib/private/user/user.php b/lib/private/user/user.php
index 3199790dba0..36680436769 100644
--- a/lib/private/user/user.php
+++ b/lib/private/user/user.php
@@ -417,5 +417,4 @@ class User implements IUser {
$this->emitter->emit('\OC\User', 'changeUser', array($this, $feature, $value));
}
}
-
}
diff --git a/lib/public/IServerContainer.php b/lib/public/IServerContainer.php
index de48daeef88..65754f993f8 100644
--- a/lib/public/IServerContainer.php
+++ b/lib/public/IServerContainer.php
@@ -519,4 +519,16 @@ interface IServerContainer {
* @since 9.0.0
*/
public function getContentSecurityPolicyManager();
+
+ /**
+ * @return \OCP\IDateTimeZone
+ * @since 8.0.0
+ */
+ public function getDateTimeZone();
+
+ /**
+ * @return \OCP\IDateTimeFormatter
+ * @since 8.0.0
+ */
+ public function getDateTimeFormatter();
}
diff --git a/lib/public/iuser.php b/lib/public/iuser.php
index b0dd8dc35b2..16617a2f2f6 100644
--- a/lib/public/iuser.php
+++ b/lib/public/iuser.php
@@ -32,6 +32,7 @@ namespace OCP;
* @since 8.0.0
*/
interface IUser {
+
/**
* get the user id
*
diff --git a/lib/public/iusermanager.php b/lib/public/iusermanager.php
index 6442938a99b..00c0bbc8721 100644
--- a/lib/public/iusermanager.php
+++ b/lib/public/iusermanager.php
@@ -142,4 +142,11 @@ interface IUserManager {
* @since 9.0.0
*/
public function callForAllUsers (\Closure $callback, $search = '');
+
+ /**
+ * @param string $email
+ * @return IUser[]
+ * @since 9.1.0
+ */
+ public function getByEmail($email);
}
diff --git a/settings/Controller/LogSettingsController.php b/settings/Controller/LogSettingsController.php
index c0c9ee04ca3..70a2b752359 100644
--- a/settings/Controller/LogSettingsController.php
+++ b/settings/Controller/LogSettingsController.php
@@ -102,7 +102,7 @@ class LogSettingsController extends Controller {
* @return StreamResponse
*/
public function download() {
- $resp = new StreamResponse(\OC_Log_Owncloud::getLogFilePath());
+ $resp = new StreamResponse(\OC\Log\Owncloud::getLogFilePath());
$resp->addHeader('Content-Disposition', 'attachment; filename="owncloud.log"');
return $resp;
}
diff --git a/tests/data/app/expected-info.json b/tests/data/app/expected-info.json
index cef7a7fdaba..81de5341efa 100644
--- a/tests/data/app/expected-info.json
+++ b/tests/data/app/expected-info.json
@@ -74,5 +74,6 @@
"post-migration": [],
"live-migration": [],
"uninstall": []
- }
+ },
+ "background-jobs": []
}
diff --git a/tests/lib/log/owncloud.php b/tests/lib/log/owncloud.php
index adecc49768c..e19063a83f5 100644
--- a/tests/lib/log/owncloud.php
+++ b/tests/lib/log/owncloud.php
@@ -15,12 +15,17 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+namespace Test\Log;
+
+use OC\Log\Owncloud;
+use Test\TestCase;
+
/**
- * Class Test_Log_Owncloud
+ * Class OwncloudTest
*
* @group DB
*/
-class Test_Log_Owncloud extends Test\TestCase
+class OwncloudTest extends TestCase
{
private $restore_logfile;
private $restore_logdateformat;
@@ -32,7 +37,7 @@ class Test_Log_Owncloud extends Test\TestCase
$this->restore_logdateformat = $config->getSystemValue('logdateformat');
$config->setSystemValue("logfile", $config->getSystemValue('datadirectory') . "/logtest");
- OC_Log_Owncloud::init();
+ Owncloud::init();
}
protected function tearDown() {
$config = \OC::$server->getConfig();
@@ -46,7 +51,7 @@ class Test_Log_Owncloud extends Test\TestCase
} else {
$config->deleteSystemValue("restore_logdateformat");
}
- OC_Log_Owncloud::init();
+ Owncloud::init();
parent::tearDown();
}
@@ -57,7 +62,7 @@ class Test_Log_Owncloud extends Test\TestCase
# set format & write log line
$config->setSystemValue('logdateformat', 'u');
- OC_Log_Owncloud::write('test', 'message', \OCP\Util::ERROR);
+ Owncloud::write('test', 'message', \OCP\Util::ERROR);
# read log line
$handle = @fopen($config->getSystemValue('logfile'), 'r');
diff --git a/tests/lib/user/session.php b/tests/lib/user/session.php
index 1c042dec9f0..5a8ea57cb86 100644
--- a/tests/lib/user/session.php
+++ b/tests/lib/user/session.php
@@ -11,19 +11,25 @@ namespace Test\User;
use OC\Session\Memory;
use OC\User\User;
+use OCP\ISession;
+use OCP\IUserManager;
+use OCP\UserInterface;
+use Test\TestCase;
/**
* @group DB
* @package Test\User
*/
-class Session extends \Test\TestCase {
+class Session extends TestCase {
public function testGetUser() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('get')
->with('user_id')
->will($this->returnValue('foo'));
+ /** @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend */
$backend = $this->getMock('\Test\Util\User\Dummy');
$backend->expects($this->once())
->method('userExists')
@@ -39,12 +45,14 @@ class Session extends \Test\TestCase {
}
public function testIsLoggedIn() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('get')
->with('user_id')
->will($this->returnValue('foo'));
+ /** @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend */
$backend = $this->getMock('\Test\Util\User\Dummy');
$backend->expects($this->once())
->method('userExists')
@@ -60,12 +68,14 @@ class Session extends \Test\TestCase {
}
public function testNotLoggedIn() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('get')
->with('user_id')
->will($this->returnValue(null));
+ /** @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend */
$backend = $this->getMock('\Test\Util\User\Dummy');
$backend->expects($this->never())
->method('userExists');
@@ -79,15 +89,18 @@ class Session extends \Test\TestCase {
}
public function testSetUser() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('set')
->with('user_id', 'foo');
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager');
$backend = $this->getMock('\Test\Util\User\Dummy');
+ /** @var User | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->once())
->method('getUID')
@@ -98,6 +111,7 @@ class Session extends \Test\TestCase {
}
public function testLoginValidPasswordEnabled() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('regenerateId');
@@ -126,12 +140,13 @@ class Session extends \Test\TestCase {
unset($managerMethods[$i]);
}
}
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
$backend = $this->getMock('\Test\Util\User\Dummy');
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
- $user->expects($this->once())
+ $user->expects($this->exactly(2))
->method('isEnabled')
->will($this->returnValue(true));
$user->expects($this->any())
@@ -150,7 +165,12 @@ class Session extends \Test\TestCase {
$this->assertEquals($user, $userSession->getUser());
}
+ /**
+ * @expectedException \OC\User\LoginException
+ * @expectedExceptionMessage User disabled
+ */
public function testLoginValidPasswordDisabled() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
@@ -167,6 +187,7 @@ class Session extends \Test\TestCase {
unset($managerMethods[$i]);
}
}
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
$backend = $this->getMock('\Test\Util\User\Dummy');
@@ -188,6 +209,7 @@ class Session extends \Test\TestCase {
}
public function testLoginInvalidPassword() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
@@ -204,6 +226,7 @@ class Session extends \Test\TestCase {
unset($managerMethods[$i]);
}
}
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
$backend = $this->getMock('\Test\Util\User\Dummy');
@@ -224,16 +247,16 @@ class Session extends \Test\TestCase {
}
public function testLoginNonExisting() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager');
- $backend = $this->getMock('\Test\Util\User\Dummy');
-
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
@@ -244,6 +267,7 @@ class Session extends \Test\TestCase {
}
public function testRememberLoginValidToken() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->exactly(1))
->method('set')
@@ -290,6 +314,7 @@ class Session extends \Test\TestCase {
$token = 'goodToken';
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time());
+ /** @var \OC\User\Session $userSession */
$userSession = $this->getMock(
'\OC\User\Session',
//override, otherwise tests will fail because of setcookie()
@@ -303,6 +328,7 @@ class Session extends \Test\TestCase {
}
public function testRememberLoginInvalidToken() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
@@ -319,6 +345,7 @@ class Session extends \Test\TestCase {
unset($managerMethods[$i]);
}
}
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
$backend = $this->getMock('\Test\Util\User\Dummy');
@@ -347,6 +374,7 @@ class Session extends \Test\TestCase {
}
public function testRememberLoginInvalidUser() {
+ /** @var ISession | \PHPUnit_Framework_MockObject_MockObject $session */
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
@@ -363,6 +391,7 @@ class Session extends \Test\TestCase {
unset($managerMethods[$i]);
}
}
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
$backend = $this->getMock('\Test\Util\User\Dummy');
@@ -395,6 +424,7 @@ class Session extends \Test\TestCase {
'bar' => new User('bar', null)
);
+ /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();