Merge pull request #11871 from nextcloud/feature/11015/collaboration-resources

Collaboration resources
This commit is contained in:
Roeland Jago Douma 2019-03-01 21:22:34 +01:00 committed by GitHub
commit 2398d1183e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 3951 additions and 1294 deletions

View File

@ -23,6 +23,8 @@ return array(
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => $baseDir . '/../lib/BackgroundJob/DeleteOrphanedItems.php',
'OCA\\Files\\BackgroundJob\\ScanFiles' => $baseDir . '/../lib/BackgroundJob/ScanFiles.php',
'OCA\\Files\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
'OCA\\Files\\Collaboration\\Resources\\Listener' => $baseDir . '/../lib/Collaboration/Resources/Listener.php',
'OCA\\Files\\Collaboration\\Resources\\ResourceProvider' => $baseDir . '/../lib/Collaboration/Resources/ResourceProvider.php',
'OCA\\Files\\Command\\DeleteOrphanedFiles' => $baseDir . '/../lib/Command/DeleteOrphanedFiles.php',
'OCA\\Files\\Command\\Scan' => $baseDir . '/../lib/Command/Scan.php',
'OCA\\Files\\Command\\ScanAppData' => $baseDir . '/../lib/Command/ScanAppData.php',

View File

@ -38,6 +38,8 @@ class ComposerStaticInitFiles
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOrphanedItems.php',
'OCA\\Files\\BackgroundJob\\ScanFiles' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScanFiles.php',
'OCA\\Files\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
'OCA\\Files\\Collaboration\\Resources\\Listener' => __DIR__ . '/..' . '/../lib/Collaboration/Resources/Listener.php',
'OCA\\Files\\Collaboration\\Resources\\ResourceProvider' => __DIR__ . '/..' . '/../lib/Collaboration/Resources/ResourceProvider.php',
'OCA\\Files\\Command\\DeleteOrphanedFiles' => __DIR__ . '/..' . '/../lib/Command/DeleteOrphanedFiles.php',
'OCA\\Files\\Command\\Scan' => __DIR__ . '/..' . '/../lib/Command/Scan.php',
'OCA\\Files\\Command\\ScanAppData' => __DIR__ . '/..' . '/../lib/Command/ScanAppData.php',

View File

@ -27,9 +27,12 @@
namespace OCA\Files\AppInfo;
use OCA\Files\Activity\Helper;
use OCA\Files\Collaboration\Resources\Listener;
use OCA\Files\Collaboration\Resources\ResourceProvider;
use OCA\Files\Controller\ApiController;
use OCP\AppFramework\App;
use \OCA\Files\Service\TagService;
use OCP\Collaboration\Resources\IManager;
use \OCP\IContainer;
use OCA\Files\Controller\ViewController;
use OCA\Files\Capabilities;
@ -99,5 +102,13 @@ class Application extends App {
* Register capabilities
*/
$container->registerCapability(Capabilities::class);
/**
* Register Collaboration ResourceProvider
*/
/** @var IManager $resourceManager */
$resourceManager = $container->query(IManager::class);
$resourceManager->registerResourceProvider(ResourceProvider::class);
Listener::register($server->getEventDispatcher());
}
}

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
*
* @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\Files\Collaboration\Resources;
use OCP\Collaboration\Resources\IManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Listener {
public static function register(EventDispatcherInterface $dispatcher): void {
$dispatcher->addListener('OCP\Share::postShare', [self::class, 'shareModification']);
$dispatcher->addListener('OCP\Share::postUnshare', [self::class, 'shareModification']);
$dispatcher->addListener('OCP\Share::postUnshareFromSelf', [self::class, 'shareModification']);
}
public static function shareModification(): void {
/** @var IManager $resourceManager */
$resourceManager = \OC::$server->query(IManager::class);
/** @var ResourceProvider $resourceProvider */
$resourceProvider = \OC::$server->query(ResourceProvider::class);
$resourceManager->invalidateAccessCacheForProvider($resourceProvider);
}
}

View File

@ -0,0 +1,140 @@
<?php
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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\Files\Collaboration\Resources;
use OCP\Collaboration\Resources\IProvider;
use OCP\Collaboration\Resources\IResource;
use OCP\Collaboration\Resources\ResourceException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\IURLGenerator;
use OCP\IUser;
class ResourceProvider implements IProvider {
const RESOURCE_TYPE = 'files';
/** @var IRootFolder */
protected $rootFolder;
/** @var IURLGenerator */
private $urlGenerator;
/** @var array */
protected $nodes = [];
public function __construct(IRootFolder $rootFolder, IURLGenerator $urlGenerator) {
$this->rootFolder = $rootFolder;
$this->urlGenerator = $urlGenerator;
}
private function getNode(IResource $resource): ?Node {
if (isset($this->nodes[(int) $resource->getId()])) {
return $this->nodes[(int) $resource->getId()];
}
$nodes = $this->rootFolder->getById((int) $resource->getId());
if (!empty($nodes)) {
$this->nodes[(int) $resource->getId()] = array_shift($nodes);
return $this->nodes[(int) $resource->getId()];
}
return null;
}
/**
* Get the display name of a resource
*
* @param IResource $resource
* @return string
* @since 15.0.0
*/
public function getName(IResource $resource): string {
if (isset($this->nodes[(int) $resource->getId()])) {
return $this->nodes[(int) $resource->getId()]->getPath();
}
$node = $this->getNode($resource);
if ($node) {
return $node->getName();
}
return '';
}
/**
* Can a user/guest access the collection
*
* @param IResource $resource
* @param IUser $user
* @return bool
* @since 15.0.0
*/
public function canAccessResource(IResource $resource, IUser $user = null): bool {
if (!$user instanceof IUser) {
return false;
}
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
$nodes = $userFolder->getById((int) $resource->getId());
if (!empty($nodes)) {
$this->nodes[(int) $resource->getId()] = array_shift($nodes);
return true;
}
return false;
}
/**
* Get the icon class of a resource
*
* @param IResource $resource
* @return string
* @since 15.0.0
*/
public function getIconClass(IResource $resource): string {
$node = $this->getNode($resource);
if ($node && $node->getMimetype() === 'httpd/unix-directory') {
return 'icon-files-dark';
}
return 'icon-filetype-file';
}
/**
* Get the resource type of the provider
*
* @return string
* @since 15.0.0
*/
public function getType(): string {
return self::RESOURCE_TYPE;
}
/**
* Get the link to a resource
*
* @param IResource $resource
* @return string
* @since 15.0.0
*/
public function getLink(IResource $resource): string {
return $this->urlGenerator->linkToRoute('files.viewcontroller.showFile', ['fileid' => $resource->getId()]);
}
}

View File

@ -27,6 +27,7 @@ namespace OCA\Files\Tests\Service;
use OC\Tags;
use OCA\Files\Service\TagService;
use OCP\Activity\IManager;
use OCP\IUser;
use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@ -75,8 +76,7 @@ class TagServiceTest extends \Test\TestCase {
\OC::$server->getUserManager()->createUser($this->user, 'test');
\OC_User::setUserId($this->user);
\OC_Util::setupFS($this->user);
/** @var \OCP\IUser */
$user = new \OC\User\User($this->user, null);
$user = $this->createMock(IUser::class);
/**
* @var \OCP\IUserSession
*/

View File

@ -64,7 +64,7 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
$this->globalStoragesService = $this->service;
$this->user = new \OC\User\User(self::USER_ID, null);
$this->user = new \OC\User\User(self::USER_ID, null, \OC::$server->getEventDispatcher());
/** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
$userSession = $this->createMock(IUserSession::class);
$userSession

View File

@ -0,0 +1,13 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['last 2 versions', 'ie >= 11']
}
}
]
],
plugins: ['@babel/plugin-syntax-dynamic-import']
}

View File

@ -0,0 +1,22 @@
module.exports = {
env: {
browser: true,
es6: true
},
globals: {
t: true,
n: true,
OC: true,
OCA: true
},
extends: 'eslint:recommended',
parserOptions: {
sourceType: 'module'
},
rules: {
indent: ['error', 'tab'],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'always']
}
};

View File

@ -42,7 +42,7 @@ $eventDispatcher = \OC::$server->getEventDispatcher();
$eventDispatcher->addListener(
'OCA\Files::loadAdditionalScripts',
function() {
\OCP\Util::addScript('files_sharing', 'additionalScripts');
\OCP\Util::addScript('files_sharing', 'dist/additionalScripts');
}
);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,24 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{13:function(e,o,i){"use strict";i.r(o);var n=i(16),l=i(18),r=i(25),s=i.n(r),a=i(26),u={name:"CollaborationView",computed:{fileId:function(){return this.$root.model&&this.$root.model.id?""+this.$root.model.id:null},filename:function(){return this.$root.model&&this.$root.model.name?""+this.$root.model.name:""}},components:{CollectionList:i(50).a}},c=i(49),d=Object(c.a)(u,function(){var t=this.$createElement,e=this._self._c||t;return this.fileId?e("collection-list",{attrs:{type:"files",id:this.fileId,name:this.filename}}):this._e()},[],!1,null,null,null).exports;i.d(o,"Vue",function(){return n.a}),i.d(o,"View",function(){return d}),
/*
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
n.a.prototype.t=t,n.a.component("PopoverMenu",l.PopoverMenu),n.a.directive("ClickOutside",s.a),n.a.directive("Tooltip",a.a)}}]);
//# sourceMappingURL=files_sharing.3.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,6 @@ $tmpl = new OCP\Template('files_sharing', 'list', '');
// gridview not available for ie
$tmpl->assign('showgridview', $showgridview && !$isIE);
OCP\Util::addScript('files_sharing', 'app');
OCP\Util::addScript('files_sharing', 'sharedfilelist');
OCP\Util::addScript('files_sharing', 'dist/files_sharing');
$tmpl->printPage();

View File

@ -1,6 +1,29 @@
__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/');
__webpack_nonce__ = btoa(OC.requestToken);
import './share'
import './sharetabview'
import './sharebreadcrumbview'
import './style/sharetabview.scss'
import './style/sharebreadcrumb.scss'
window.OCP.Collaboration.registerType('files', {
action: () => {
return new Promise((resolve, reject) => {
OC.dialogs.filepicker('Link to a file', function (f) {
const client = OC.Files.getClient();
client.getFileInfo(f).then((status, fileInfo) => {
resolve(fileInfo.id);
}, () => {
reject();
});
}, false);
});
},
/** used in "Link to a {typeString}" */
typeString: t('files_sharing', 'file'),
typeIconClass: 'icon-files-dark'
});
window.OCA.Sharing = OCA.Sharing;

View File

@ -0,0 +1,39 @@
/*
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
import Vue from 'vue';
import { PopoverMenu } from 'nextcloud-vue';
import ClickOutside from 'vue-click-outside';
import { VTooltip } from 'v-tooltip';
Vue.prototype.t = t;
Vue.component('PopoverMenu', PopoverMenu);
Vue.directive('ClickOutside', ClickOutside);
Vue.directive('Tooltip', VTooltip);
import View from './views/CollaborationView';
export {
Vue,
View
};

View File

@ -0,0 +1,5 @@
__webpack_nonce__ = btoa(OC.requestToken);
__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/');
import '../js/app';
import '../js/sharedfilelist';

View File

@ -14,6 +14,7 @@
var TEMPLATE =
'<div>' +
'<div class="dialogContainer"></div>' +
'<div id="collaborationResources"></div>' +
'</div>';
/**
@ -81,6 +82,19 @@
this._dialog.model.on('change', function() {
self.trigger('sharesChanged', shareModel);
});
import('./collaborationresources').then((Resources) => {
var vm = new Resources.Vue({
el: '#collaborationResources',
render: h => h(Resources.View),
data: {
model: this.model.toJSON()
},
});
this.model.on('change', () => { vm.data = this.model.toJSON() })
})
} else {
this.$el.empty();
// TODO: render placeholder text?

View File

@ -0,0 +1,57 @@
<!--
- @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
-
- @author Julius Härtl <jus@bitgrid.net>
-
- @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/>.
-
-->
<template>
<collection-list v-if="fileId" type="files" :id="fileId" :name="filename"></collection-list>
</template>
<script>
import { CollectionList } from 'nextcloud-vue-collections'
/**
* Those translations will be used by the vue component but they should be shipped with the server
* t('files_sharing', 'Add to a collection')
* t('files_sharing', 'Details')
* t('files_sharing', 'Rename collection')
*/
export default {
name: 'CollaborationView',
computed: {
fileId() {
if (this.$root.model && this.$root.model.id) {
return '' + this.$root.model.id;
}
return null;
},
filename() {
if (this.$root.model && this.$root.model.name) {
return '' + this.$root.model.name;
}
return '';
}
},
components: {
CollectionList
}
}
</script>

View File

@ -1,26 +1,39 @@
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
entry: path.join(__dirname, 'src', 'additionalScripts.js'),
entry: {
'additionalScripts': path.join(__dirname, 'src', 'additionalScripts.js'),
'files_sharing': path.join(__dirname, 'src', 'files_sharing.js'),
},
output: {
path: path.resolve(__dirname, './js'),
path: path.resolve(__dirname, './js/dist/'),
publicPath: '/js/',
filename: 'additionalScripts.js'
filename: '[name].js',
chunkFilename: 'files_sharing.[id].js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
use: ['vue-style-loader', 'css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
use: ['vue-style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
exclude: /node_modules/,
options: {
plugins: ['@babel/plugin-syntax-dynamic-import', 'transform-es2015-arrow-functions']
}
},
{
test: /\.(png|jpg|gif|svg)$/,
@ -31,7 +44,14 @@ module.exports = {
}
]
},
plugins: [new VueLoaderPlugin()],
resolve: {
extensions: ['*', '.js']
}
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
},
extensions: ['*', '.js', '.vue', '.json'],
modules: [
path.join(__dirname, '../../node_modules')
]
},
};

View File

@ -25,10 +25,12 @@
namespace OCA\User_LDAP\Tests;
use OC\User\Manager;
use OCA\User_LDAP\IGroupLDAP;
use OCP\IConfig;
use OCP\IServerContainer;
use OCA\User_LDAP\IUserLDAP;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class LDAPProviderTest
@ -60,21 +62,21 @@ class LDAPProviderTest extends \Test\TestCase {
$server->expects($this->any())
->method($this->anything())
->willReturnSelf();
return $server;
}
private function getUserManagerMock(IUserLDAP $userBackend) {
$userManager = $this->getMockBuilder('OC\User\Manager')
$userManager = $this->getMockBuilder(Manager::class)
->setMethods(['getBackends'])
->setConstructorArgs([$this->createMock(IConfig::class)])
->setConstructorArgs([$this->createMock(IConfig::class), $this->createMock(EventDispatcherInterface::class)])
->getMock();
$userManager->expects($this->any())
->method('getBackends')
->willReturn([$userBackend]);
return $userManager;
}
private function getGroupManagerMock(IGroupLDAP $groupBackend) {
$groupManager = $this->getMockBuilder('OC\Group\Manager')
->setMethods(['getBackends'])

View File

@ -0,0 +1,252 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\OCSController;
use OCP\AppFramework\Http\DataResponse;
use OCP\Collaboration\Resources\CollectionException;
use OCP\Collaboration\Resources\ICollection;
use OCP\Collaboration\Resources\IManager;
use OCP\Collaboration\Resources\IResource;
use OCP\Collaboration\Resources\ResourceException;
use OCP\IRequest;
use OCP\IUserSession;
class CollaborationResourcesController extends OCSController {
/** @var IManager */
private $manager;
/** @var IUserSession */
private $userSession;
public function __construct(
string $appName,
IRequest $request,
IManager $manager,
IUserSession $userSession
) {
parent::__construct($appName, $request);
$this->manager = $manager;
$this->userSession = $userSession;
}
/**
* @param int $collectionId
* @return ICollection
* @throws CollectionException when the collection was not found for the user
*/
protected function getCollection(int $collectionId): ICollection {
$collection = $this->manager->getCollectionForUser($collectionId, $this->userSession->getUser());
if (!$collection->canAccess($this->userSession->getUser())) {
throw new CollectionException('Not found');
}
return $collection;
}
/**
* @NoAdminRequired
*
* @param int $collectionId
* @return DataResponse
*/
public function listCollection(int $collectionId): DataResponse {
try {
$collection = $this->getCollection($collectionId);
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
return new DataResponse($this->prepareCollection($collection));
}
/**
* @NoAdminRequired
*
* @param string $filter
* @return DataResponse
*/
public function searchCollections(string $filter): DataResponse {
try {
$collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
return new DataResponse(array_map([$this, 'prepareCollection'], $collections));
}
/**
* @NoAdminRequired
*
* @param int $collectionId
* @param string $resourceType
* @param string $resourceId
* @return DataResponse
*/
public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
try {
$collection = $this->getCollection($collectionId);
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$resource = $this->manager->createResource($resourceType, $resourceId);
if (!$resource->canAccess($this->userSession->getUser())) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
try {
$collection->addResource($resource);
} catch (ResourceException $e) {
}
return new DataResponse($this->prepareCollection($collection));
}
/**
* @NoAdminRequired
*
* @param int $collectionId
* @param string $resourceType
* @param string $resourceId
* @return DataResponse
*/
public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
try {
$collection = $this->getCollection($collectionId);
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
try {
$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$collection->removeResource($resource);
return new DataResponse($this->prepareCollection($collection));
}
/**
* @NoAdminRequired
*
* @param string $resourceType
* @param string $resourceId
* @return DataResponse
*/
public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
try {
$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
} catch (ResourceException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!$resource->canAccess($this->userSession->getUser())) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
return new DataResponse(array_map([$this, 'prepareCollection'], $resource->getCollections()));
}
/**
* @NoAdminRequired
*
* @param string $baseResourceType
* @param string $baseResourceId
* @param string $name
* @return DataResponse
*/
public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
if (!isset($name[0]) || isset($name[64])) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
try {
$resource = $this->manager->createResource($baseResourceType, $baseResourceId);
} catch (CollectionException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!$resource->canAccess($this->userSession->getUser())) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$collection = $this->manager->newCollection($name);
$collection->addResource($resource);
return new DataResponse($this->prepareCollection($collection));
}
/**
* @NoAdminRequired
*
* @param int $collectionId
* @param string $collectionName
* @return DataResponse
*/
public function renameCollection(int $collectionId, string $collectionName): DataResponse {
try {
$collection = $this->getCollection($collectionId);
} catch (CollectionException $exception) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$collection->setName($collectionName);
return new DataResponse($this->prepareCollection($collection));
}
protected function prepareCollection(ICollection $collection): array {
if (!$collection->canAccess($this->userSession->getUser())) {
return null;
}
return [
'id' => $collection->getId(),
'name' => $collection->getName(),
'resources' => array_values(array_filter(array_map([$this, 'prepareResources'], $collection->getResources()))),
];
}
protected function prepareResources(IResource $resource): ?array {
if (!$resource->canAccess($this->userSession->getUser())) {
return null;
}
return [
'type' => $resource->getType(),
'id' => $resource->getId(),
'name' => $resource->getName(),
'iconClass' => $resource->getIconClass(),
'link' => $resource->getLink(),
];
}
}

View File

@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Migrations;
use Closure;
use Doctrine\DBAL\Types\Type;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
class Version16000Date20190207141427 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('collres_collections')) {
$table = $schema->createTable('collres_collections');
$table->addColumn('id', Type::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('name', Type::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->setPrimaryKey(['id']);
}
if (!$schema->hasTable('collres_resources')) {
$table = $schema->createTable('collres_resources');
$table->addColumn('collection_id', Type::BIGINT, [
'notnull' => true,
]);
$table->addColumn('resource_type', Type::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('resource_id', Type::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addUniqueIndex(['collection_id', 'resource_type', 'resource_id'], 'collres_unique_res');
}
if (!$schema->hasTable('collres_accesscache')) {
$table = $schema->createTable('collres_accesscache');
$table->addColumn('user_id', Type::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('collection_id', Type::BIGINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('resource_type', Type::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->addColumn('resource_id', Type::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->addColumn('access', Type::SMALLINT, [
'notnull' => true,
'default' => 0,
]);
$table->addUniqueIndex(['user_id', 'collection_id', 'resource_type', 'resource_id'], 'collres_unique_user');
$table->addIndex(['user_id', 'resource_type', 'resource_id'], 'collres_user_res');
$table->addIndex(['user_id', 'collection_id'], 'collres_user_coll');
}
return $schema;
}
}

View File

@ -384,6 +384,10 @@ img, object, video, button, textarea, input, select, div[contenteditable='true']
@include icon-color('text', 'filetypes', $color-black, 1, true);
}
.icon-filetype-file {
@include icon-color('file', 'filetypes', $color-black, 1, true);
}
@include icon-black-white('folder', 'filetypes', 1, true);
.icon-filetype-folder {
@include icon-color('folder', 'filetypes', $color-black, 1, true);

48
core/js/dist/main.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -90,7 +90,8 @@ window.oc_isadmin = false;
// FIXME: oc_webroot is supposed to be only the path!!!
window.oc_webroot = location.href + '/';
window.oc_appswebroots = {
"files": window.oc_webroot + '/apps/files/'
"files": window.oc_webroot + '/apps/files/',
"files_sharing": window.oc_webroot + '/apps/files_sharing/'
};
window.oc_config = {
session_lifetime: 600 * 1000,

View File

@ -90,6 +90,15 @@ $application->registerRoutes($this, [
['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
['root' => '/core', 'name' => 'AppPassword#getAppPassword', 'url' => '/getapppassword', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#searchCollections', 'url' => '/resources/collections/search/{filter}', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#listCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#renameCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'PUT'],
['root' => '/collaboration', 'name' => 'CollaborationResources#addResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'POST'],
['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'],
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
],
]);

View File

@ -0,0 +1,61 @@
/*
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
/**
* @typedef TypeDefinition
* @method {callback} action This action is executed to let the user select a resource
* @param {string} icon Contains the icon css class for the type
* @constructor
*/
/**
* @type {TypeDefinition[]}
**/
let types = {};
export default {
/**
*
* @param type
* @param {TypeDefinition} typeDefinition
*/
registerType(type, typeDefinition) {
console.log('Type ' + type + ' registered')
types[type] = typeDefinition;
},
trigger(type) {
return types[type].action()
},
getTypes() {
return Object.keys(types);
},
getIcon(type) {
return types[type].typeIconClass || '';
},
getLabel(type) {
return t('files_sharing', 'Link to a {label}', { label: types[type].typeString || type }, 1)
},
getLink(type, id) {
/* TODO: Allow action to be executed instead of href as well */
return typeof types[type] !== 'undefined' ? types[type].link(id) : '';
}
};

View File

@ -5,6 +5,7 @@ import * as AppConfig from './appconfig'
import * as Comments from './comments'
import * as InitialState from './initialstate'
import Loader from './loader'
import Collaboration from './collaboration'
import * as WhatsNew from './whatsnew'
/** @namespace OCP */
@ -14,4 +15,5 @@ export default {
InitialState,
Loader,
WhatsNew,
Collaboration
};

View File

@ -716,6 +716,7 @@ class OC {
self::registerEncryptionWrapper();
self::registerEncryptionHooks();
self::registerAccountHooks();
self::registerResourceCollectionHooks();
// Make sure that the application class is not loaded before the database is setup
if ($systemConfig->getValue("installed", false)) {
@ -847,6 +848,10 @@ class OC {
\OCP\Util::connectHook('OC_User', 'changeUser', $hookHandler, 'changeUserHook');
}
private static function registerResourceCollectionHooks() {
\OC\Collaboration\Resources\Listener::register(\OC::$server->getEventDispatcher());
}
/**
* register hooks for the filesystem
*/

View File

@ -112,6 +112,12 @@ return array(
'OCP\\Collaboration\\Collaborators\\ISearchPlugin' => $baseDir . '/lib/public/Collaboration/Collaborators/ISearchPlugin.php',
'OCP\\Collaboration\\Collaborators\\ISearchResult' => $baseDir . '/lib/public/Collaboration/Collaborators/ISearchResult.php',
'OCP\\Collaboration\\Collaborators\\SearchResultType' => $baseDir . '/lib/public/Collaboration/Collaborators/SearchResultType.php',
'OCP\\Collaboration\\Resources\\CollectionException' => $baseDir . '/lib/public/Collaboration/Resources/CollectionException.php',
'OCP\\Collaboration\\Resources\\ICollection' => $baseDir . '/lib/public/Collaboration/Resources/ICollection.php',
'OCP\\Collaboration\\Resources\\IManager' => $baseDir . '/lib/public/Collaboration/Resources/IManager.php',
'OCP\\Collaboration\\Resources\\IProvider' => $baseDir . '/lib/public/Collaboration/Resources/IProvider.php',
'OCP\\Collaboration\\Resources\\IResource' => $baseDir . '/lib/public/Collaboration/Resources/IResource.php',
'OCP\\Collaboration\\Resources\\ResourceException' => $baseDir . '/lib/public/Collaboration/Resources/ResourceException.php',
'OCP\\Command\\IBus' => $baseDir . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => $baseDir . '/lib/public/Command/ICommand.php',
'OCP\\Comments\\CommentsEntityEvent' => $baseDir . '/lib/public/Comments/CommentsEntityEvent.php',
@ -544,6 +550,10 @@ return array(
'OC\\Collaboration\\Collaborators\\Search' => $baseDir . '/lib/private/Collaboration/Collaborators/Search.php',
'OC\\Collaboration\\Collaborators\\SearchResult' => $baseDir . '/lib/private/Collaboration/Collaborators/SearchResult.php',
'OC\\Collaboration\\Collaborators\\UserPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/UserPlugin.php',
'OC\\Collaboration\\Resources\\Collection' => $baseDir . '/lib/private/Collaboration/Resources/Collection.php',
'OC\\Collaboration\\Resources\\Listener' => $baseDir . '/lib/private/Collaboration/Resources/Listener.php',
'OC\\Collaboration\\Resources\\Manager' => $baseDir . '/lib/private/Collaboration/Resources/Manager.php',
'OC\\Collaboration\\Resources\\Resource' => $baseDir . '/lib/private/Collaboration/Resources/Resource.php',
'OC\\Color' => $baseDir . '/lib/private/Color.php',
'OC\\Command\\AsyncBus' => $baseDir . '/lib/private/Command/AsyncBus.php',
'OC\\Command\\CallableJob' => $baseDir . '/lib/private/Command/CallableJob.php',
@ -659,6 +669,7 @@ return array(
'OC\\Core\\Controller\\CSRFTokenController' => $baseDir . '/core/Controller/CSRFTokenController.php',
'OC\\Core\\Controller\\ClientFlowLoginController' => $baseDir . '/core/Controller/ClientFlowLoginController.php',
'OC\\Core\\Controller\\ClientFlowLoginV2Controller' => $baseDir . '/core/Controller/ClientFlowLoginV2Controller.php',
'OC\\Core\\Controller\\CollaborationResourcesController' => $baseDir . '/core/Controller/CollaborationResourcesController.php',
'OC\\Core\\Controller\\ContactsMenuController' => $baseDir . '/core/Controller/ContactsMenuController.php',
'OC\\Core\\Controller\\CssController' => $baseDir . '/core/Controller/CssController.php',
'OC\\Core\\Controller\\GuestAvatarController' => $baseDir . '/core/Controller/GuestAvatarController.php',
@ -698,6 +709,7 @@ return array(
'OC\\Core\\Migrations\\Version15000Date20180926101451' => $baseDir . '/core/Migrations/Version15000Date20180926101451.php',
'OC\\Core\\Migrations\\Version15000Date20181015062942' => $baseDir . '/core/Migrations/Version15000Date20181015062942.php',
'OC\\Core\\Migrations\\Version15000Date20181029084625' => $baseDir . '/core/Migrations/Version15000Date20181029084625.php',
'OC\\Core\\Migrations\\Version16000Date20190207141427' => $baseDir . '/core/Migrations/Version16000Date20190207141427.php',
'OC\\Core\\Migrations\\Version16000Date20190212081545' => $baseDir . '/core/Migrations/Version16000Date20190212081545.php',
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php',
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',

View File

@ -142,6 +142,12 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Collaboration\\Collaborators\\ISearchPlugin' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Collaborators/ISearchPlugin.php',
'OCP\\Collaboration\\Collaborators\\ISearchResult' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Collaborators/ISearchResult.php',
'OCP\\Collaboration\\Collaborators\\SearchResultType' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Collaborators/SearchResultType.php',
'OCP\\Collaboration\\Resources\\CollectionException' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/CollectionException.php',
'OCP\\Collaboration\\Resources\\ICollection' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/ICollection.php',
'OCP\\Collaboration\\Resources\\IManager' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/IManager.php',
'OCP\\Collaboration\\Resources\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/IProvider.php',
'OCP\\Collaboration\\Resources\\IResource' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/IResource.php',
'OCP\\Collaboration\\Resources\\ResourceException' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/ResourceException.php',
'OCP\\Command\\IBus' => __DIR__ . '/../../..' . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => __DIR__ . '/../../..' . '/lib/public/Command/ICommand.php',
'OCP\\Comments\\CommentsEntityEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEntityEvent.php',
@ -574,6 +580,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Collaboration\\Collaborators\\Search' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/Search.php',
'OC\\Collaboration\\Collaborators\\SearchResult' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/SearchResult.php',
'OC\\Collaboration\\Collaborators\\UserPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/UserPlugin.php',
'OC\\Collaboration\\Resources\\Collection' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Resources/Collection.php',
'OC\\Collaboration\\Resources\\Listener' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Resources/Listener.php',
'OC\\Collaboration\\Resources\\Manager' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Resources/Manager.php',
'OC\\Collaboration\\Resources\\Resource' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Resources/Resource.php',
'OC\\Color' => __DIR__ . '/../../..' . '/lib/private/Color.php',
'OC\\Command\\AsyncBus' => __DIR__ . '/../../..' . '/lib/private/Command/AsyncBus.php',
'OC\\Command\\CallableJob' => __DIR__ . '/../../..' . '/lib/private/Command/CallableJob.php',
@ -689,6 +699,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Controller\\CSRFTokenController' => __DIR__ . '/../../..' . '/core/Controller/CSRFTokenController.php',
'OC\\Core\\Controller\\ClientFlowLoginController' => __DIR__ . '/../../..' . '/core/Controller/ClientFlowLoginController.php',
'OC\\Core\\Controller\\ClientFlowLoginV2Controller' => __DIR__ . '/../../..' . '/core/Controller/ClientFlowLoginV2Controller.php',
'OC\\Core\\Controller\\CollaborationResourcesController' => __DIR__ . '/../../..' . '/core/Controller/CollaborationResourcesController.php',
'OC\\Core\\Controller\\ContactsMenuController' => __DIR__ . '/../../..' . '/core/Controller/ContactsMenuController.php',
'OC\\Core\\Controller\\CssController' => __DIR__ . '/../../..' . '/core/Controller/CssController.php',
'OC\\Core\\Controller\\GuestAvatarController' => __DIR__ . '/../../..' . '/core/Controller/GuestAvatarController.php',
@ -728,6 +739,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Migrations\\Version15000Date20180926101451' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20180926101451.php',
'OC\\Core\\Migrations\\Version15000Date20181015062942' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20181015062942.php',
'OC\\Core\\Migrations\\Version15000Date20181029084625' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20181029084625.php',
'OC\\Core\\Migrations\\Version16000Date20190207141427' => __DIR__ . '/../../..' . '/core/Migrations/Version16000Date20190207141427.php',
'OC\\Core\\Migrations\\Version16000Date20190212081545' => __DIR__ . '/../../..' . '/core/Migrations/Version16000Date20190212081545.php',
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php',
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',

View File

@ -283,6 +283,7 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $dispatcher;
});
$this->registerAlias(\OCP\Collaboration\Resources\IManager::class, OC\Collaboration\Resources\Manager::class);
}
/**

View File

@ -0,0 +1,228 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Collaboration\Resources;
use Doctrine\DBAL\Exception\ConstraintViolationException;
use OCP\Collaboration\Resources\IManager;
use OCP\Collaboration\Resources\ResourceException;
use OCP\Collaboration\Resources\ICollection;
use OCP\Collaboration\Resources\IResource;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
class Collection implements ICollection {
/** @var IManager|Manager */
protected $manager;
/** @var IDBConnection */
protected $connection;
/** @var int */
protected $id;
/** @var string */
protected $name;
/** @var IUser|null */
protected $userForAccess;
/** @var bool|null */
protected $access;
/** @var IResource[] */
protected $resources;
public function __construct(
IManager $manager,
IDBConnection $connection,
int $id,
string $name,
?IUser $userForAccess = null,
?bool $access = null
) {
$this->manager = $manager;
$this->connection = $connection;
$this->id = $id;
$this->name = $name;
$this->userForAccess = $userForAccess;
$this->access = $access;
$this->resources = [];
}
/**
* @return int
* @since 16.0.0
*/
public function getId(): int {
return $this->id;
}
/**
* @return string
* @since 16.0.0
*/
public function getName(): string {
return $this->name;
}
/**
* @param string $name
* @since 16.0.0
*/
public function setName(string $name): void {
$query = $this->connection->getQueryBuilder();
$query->update(Manager::TABLE_COLLECTIONS)
->set('name', $query->createNamedParameter($name))
->where($query->expr()->eq('id', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT)));
$query->execute();
$this->name = $name;
}
/**
* @return IResource[]
* @since 16.0.0
*/
public function getResources(): array {
if (empty($this->resources)) {
$this->resources = $this->manager->getResourcesByCollectionForUser($this, $this->userForAccess);
}
return $this->resources;
}
/**
* Adds a resource to a collection
*
* @param IResource $resource
* @throws ResourceException when the resource is already part of the collection
* @since 16.0.0
*/
public function addResource(IResource $resource): void {
array_map(function(IResource $r) use ($resource) {
if ($this->isSameResource($r, $resource)) {
throw new ResourceException('Already part of the collection');
}
}, $this->getResources());
$this->resources[] = $resource;
$query = $this->connection->getQueryBuilder();
$query->insert(Manager::TABLE_RESOURCES)
->values([
'collection_id' => $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT),
'resource_type' => $query->createNamedParameter($resource->getType()),
'resource_id' => $query->createNamedParameter($resource->getId()),
]);
try {
$query->execute();
} catch (ConstraintViolationException $e) {
throw new ResourceException('Already part of the collection');
}
$this->manager->invalidateAccessCacheForCollection($this);
}
/**
* Removes a resource from a collection
*
* @param IResource $resource
* @since 16.0.0
*/
public function removeResource(IResource $resource): void {
$this->resources = array_filter($this->getResources(), function(IResource $r) use ($resource) {
return !$this->isSameResource($r, $resource);
});
$query = $this->connection->getQueryBuilder();
$query->delete(Manager::TABLE_RESOURCES)
->where($query->expr()->eq('collection_id', $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType())))
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())));
$query->execute();
if (empty($this->resources)) {
$this->removeCollection();
} else {
$this->manager->invalidateAccessCacheForCollection($this);
}
}
/**
* Can a user/guest access the collection
*
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccess(?IUser $user): bool {
if ($user instanceof IUser) {
return $this->canUserAccess($user);
}
return $this->canGuestAccess();
}
protected function canUserAccess(IUser $user): bool {
if (\is_bool($this->access) && $this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
return $this->access;
}
$access = $this->manager->canAccessCollection($this, $user);
if ($this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
$this->access = $access;
}
return $access;
}
protected function canGuestAccess(): bool {
if (\is_bool($this->access) && !$this->userForAccess instanceof IUser) {
return $this->access;
}
$access = $this->manager->canAccessCollection($this, null);
if (!$this->userForAccess instanceof IUser) {
$this->access = $access;
}
return $access;
}
protected function isSameResource(IResource $resource1, IResource $resource2): bool {
return $resource1->getType() === $resource2->getType() &&
$resource1->getId() === $resource2->getId();
}
protected function removeCollection(): void {
$query = $this->connection->getQueryBuilder();
$query->delete(Manager::TABLE_COLLECTIONS)
->where($query->expr()->eq('id', $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT)));
$query->execute();
$this->manager->invalidateAccessCacheForCollection($this);
$this->id = 0;
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Collaboration\Resources;
use OCP\Collaboration\Resources\IManager;
use OCP\IGroup;
use OCP\IUser;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
class Listener {
public static function register(EventDispatcherInterface $dispatcher): void {
$listener = function(GenericEvent $event) {
/** @var IUser $user */
$user = $event->getArgument('user');
/** @var IManager $resourceManager */
$resourceManager = \OC::$server->query(IManager::class);
$resourceManager->invalidateAccessCacheForUser($user);
};
$dispatcher->addListener(IGroup::class . '::postAddUser', $listener);
$dispatcher->addListener(IGroup::class . '::postRemoveUser', $listener);
$dispatcher->addListener(IUser::class . '::postDelete', function(GenericEvent $event) {
/** @var IUser $user */
$user = $event->getSubject();
/** @var IManager $resourceManager */
$resourceManager = \OC::$server->query(IManager::class);
$resourceManager->invalidateAccessCacheForUser($user);
});
$dispatcher->addListener(IGroup::class . '::preDelete', function(GenericEvent $event) {
/** @var IGroup $group */
$group = $event->getSubject();
/** @var IManager $resourceManager */
$resourceManager = \OC::$server->query(IManager::class);
foreach ($group->getUsers() as $user) {
$resourceManager->invalidateAccessCacheForUser($user);
}
});
}
}

View File

@ -0,0 +1,564 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Collaboration\Resources;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCP\AppFramework\QueryException;
use OCP\Collaboration\Resources\CollectionException;
use OCP\Collaboration\Resources\ICollection;
use OCP\Collaboration\Resources\IManager;
use OCP\Collaboration\Resources\IProvider;
use OCP\Collaboration\Resources\IResource;
use OCP\Collaboration\Resources\ResourceException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\ILogger;
use OCP\IUser;
class Manager implements IManager {
public const TABLE_COLLECTIONS = 'collres_collections';
public const TABLE_RESOURCES = 'collres_resources';
public const TABLE_ACCESS_CACHE = 'collres_accesscache';
/** @var IDBConnection */
protected $connection;
/** @var ILogger */
protected $logger;
/** @var string[] */
protected $providers = [];
/** @var IProvider[] */
protected $providerInstances = [];
public function __construct(IDBConnection $connection, ILogger $logger) {
$this->connection = $connection;
$this->logger = $logger;
}
/**
* @param int $id
* @return ICollection
* @throws CollectionException when the collection could not be found
* @since 16.0.0
*/
public function getCollection(int $id): ICollection {
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from(self::TABLE_COLLECTIONS)
->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
$result = $query->execute();
$row = $result->fetch();
$result->closeCursor();
if (!$row) {
throw new CollectionException('Collection not found');
}
return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name']);
}
/**
* @param int $id
* @param IUser|null $user
* @return ICollection
* @throws CollectionException when the collection could not be found
* @since 16.0.0
*/
public function getCollectionForUser(int $id, ?IUser $user): ICollection {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('*')
->from(self::TABLE_COLLECTIONS, 'c')
->leftJoin(
'c', self::TABLE_ACCESS_CACHE, 'a',
$query->expr()->andX(
$query->expr()->eq('c.id', 'a.collection_id'),
$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
)
)
->where($query->expr()->eq('c.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
$result = $query->execute();
$row = $result->fetch();
$result->closeCursor();
if (!$row) {
throw new CollectionException('Collection not found');
}
$access = $row['access'] === null ? null : (bool) $row['access'];
if ($user instanceof IUser) {
return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
}
return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
}
/**
* @param IUser $user
* @param string $filter
* @param int $limit
* @param int $start
* @return ICollection[]
* @since 16.0.0
*/
public function searchCollections(IUser $user, string $filter, int $limit = 50, int $start = 0): array {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('c.*', 'a.access')
->from(self::TABLE_COLLECTIONS, 'c')
->leftJoin(
'c', self::TABLE_ACCESS_CACHE, 'a',
$query->expr()->andX(
$query->expr()->eq('c.id', 'a.collection_id'),
$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
)
)
->where($query->expr()->iLike('c.name', $query->createNamedParameter($filter, IQueryBuilder::PARAM_STR)))
->andWhere($query->expr()->eq('a.access', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
->orderBy('c.id')
->setMaxResults($limit)
->setFirstResult($start);
$result = $query->execute();
$collections = [];
$foundResults = 0;
while ($row = $result->fetch()) {
$foundResults++;
$access = $row['access'] === null ? null : (bool) $row['access'];
$collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
if ($collection->canAccess($user)) {
$collections[] = $collection;
}
}
$result->closeCursor();
if (empty($collections) && $foundResults === $limit) {
$this->searchCollections($user, $filter, $limit, $start + $limit);
}
return $collections;
}
/**
* @param string $name
* @return ICollection
* @since 16.0.0
*/
public function newCollection(string $name): ICollection {
$query = $this->connection->getQueryBuilder();
$query->insert(self::TABLE_COLLECTIONS)
->values([
'name' => $query->createNamedParameter($name),
]);
$query->execute();
return new Collection($this, $this->connection, $query->getLastInsertId(), $name);
}
/**
* @param string $type
* @param string $id
* @return IResource
* @since 16.0.0
*/
public function createResource(string $type, string $id): IResource {
return new Resource($this, $this->connection, $type, $id);
}
/**
* @param string $type
* @param string $id
* @param IUser|null $user
* @return IResource
* @throws ResourceException
* @since 16.0.0
*/
public function getResourceForUser(string $type, string $id, ?IUser $user): IResource {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('r.*', 'a.access')
->from(self::TABLE_RESOURCES, 'r')
->leftJoin(
'r', self::TABLE_ACCESS_CACHE, 'a',
$query->expr()->andX(
$query->expr()->eq('r.resource_id', 'a.resource_id'),
$query->expr()->eq('r.resource_type', 'a.resource_type'),
$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
)
)
->where($query->expr()->eq('r.resource_type', $query->createNamedParameter($type, IQueryBuilder::PARAM_STR)))
->andWhere($query->expr()->eq('r.resource_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR)));
$result = $query->execute();
$row = $result->fetch();
$result->closeCursor();
if (!$row) {
throw new ResourceException('Resource not found');
}
$access = $row['access'] === null ? null : (bool) $row['access'];
if ($user instanceof IUser) {
return new Resource($this, $this->connection, $type, $id, $user, $access);
}
return new Resource($this, $this->connection, $type, $id, null, $access);
}
/**
* @param ICollection $collection
* @param IUser|null $user
* @return IResource[]
* @since 16.0.0
*/
public function getResourcesByCollectionForUser(ICollection $collection, ?IUser $user): array {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('r.*', 'a.access')
->from(self::TABLE_RESOURCES, 'r')
->leftJoin(
'r', self::TABLE_ACCESS_CACHE, 'a',
$query->expr()->andX(
$query->expr()->eq('r.resource_id', 'a.resource_id'),
$query->expr()->eq('r.resource_type', 'a.resource_type'),
$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
)
)
->where($query->expr()->eq('r.collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)));
$resources = [];
$result = $query->execute();
while ($row = $result->fetch()) {
$access = $row['access'] === null ? null : (bool) $row['access'];
$resources[] = new Resource($this, $this->connection, $row['resource_type'], $row['resource_id'], $user, $access);
}
$result->closeCursor();
return $resources;
}
/**
* @return IProvider[]
* @since 16.0.0
*/
public function getProviders(): array {
if (!empty($this->providers)) {
foreach ($this->providers as $provider) {
try {
$this->providerInstances[] = \OC::$server->query($provider);
} catch (QueryException $e) {
$this->logger->logException($e, [
'message' => 'Error when instantiating resource provider'
]);
}
}
$this->providers = [];
}
return $this->providerInstances;
}
/**
* Get the display name of a resource
*
* @param IResource $resource
* @return string
* @since 16.0.0
*/
public function getName(IResource $resource): string {
foreach ($this->getProviders() as $provider) {
if ($provider->getType() === $resource->getType()) {
try {
return $provider->getName($resource);
} catch (ResourceException $e) {
}
}
}
return '';
}
/**
*
* @param IResource $resource
* @return string
*/
public function getIconClass(IResource $resource): string {
foreach ($this->getProviders() as $provider) {
if ($provider->getType() === $resource->getType()) {
try {
return $provider->getIconClass($resource);
} catch (ResourceException $e) {
}
}
}
return '';
}
/**
* Can a user/guest access the collection
*
* @param IResource $resource
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccessResource(IResource $resource, ?IUser $user): bool {
$access = $this->checkAccessCacheForUserByResource($resource, $user);
if (\is_bool($access)) {
return $access;
}
$access = false;
foreach ($this->getProviders() as $provider) {
if ($provider->getType() === $resource->getType()) {
try {
if ($provider->canAccessResource($resource, $user)) {
$access = true;
break;
}
} catch (ResourceException $e) {
}
}
}
$this->cacheAccessForResource($resource, $user, $access);
return $access;
}
/**
* Can a user/guest access the collection
*
* @param ICollection $collection
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccessCollection(ICollection $collection, ?IUser $user): bool {
$access = $this->checkAccessCacheForUserByCollection($collection, $user);
if (\is_bool($access)) {
return $access;
}
$access = false;
foreach ($collection->getResources() as $resource) {
if ($resource->canAccess($user)) {
$access = true;
break;
}
}
$this->cacheAccessForCollection($collection, $user, $access);
return $access;
}
protected function checkAccessCacheForUserByResource(IResource $resource, ?IUser $user): ?bool {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('access')
->from(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId(), IQueryBuilder::PARAM_STR)))
->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)))
->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
->setMaxResults(1);
$hasAccess = null;
$result = $query->execute();
if ($row = $result->fetch()) {
$hasAccess = (bool) $row['access'];
}
$result->closeCursor();
return $hasAccess;
}
protected function checkAccessCacheForUserByCollection(ICollection $collection, ?IUser $user): ?bool {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->select('access')
->from(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
->setMaxResults(1);
$hasAccess = null;
$result = $query->execute();
if ($row = $result->fetch()) {
$hasAccess = (bool) $row['access'];
}
$result->closeCursor();
return $hasAccess;
}
public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->insert(self::TABLE_ACCESS_CACHE)
->values([
'user_id' => $query->createNamedParameter($userId),
'resource_id' => $query->createNamedParameter($resource->getId()),
'resource_type' => $query->createNamedParameter($resource->getType()),
'access' => $query->createNamedParameter($access),
]);
try {
$query->execute();
} catch (UniqueConstraintViolationException $e) {
}
}
public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->insert(self::TABLE_ACCESS_CACHE)
->values([
'user_id' => $query->createNamedParameter($userId),
'collection_id' => $query->createNamedParameter($collection->getId()),
'access' => $query->createNamedParameter($access),
]);
try {
$query->execute();
} catch (UniqueConstraintViolationException $e) {
}
}
public function invalidateAccessCacheForUser(?IUser $user): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
$query->execute();
}
public function invalidateAccessCacheForResource(IResource $resource): void {
$query = $this->connection->getQueryBuilder();
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)));
$query->execute();
foreach ($resource->getCollections() as $collection) {
$this->invalidateAccessCacheForCollection($collection);
}
}
public function invalidateAccessCacheForCollection(ICollection $collection): void {
$query = $this->connection->getQueryBuilder();
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())));
$query->execute();
}
public function invalidateAccessCacheForProvider(IProvider $provider): void {
$query = $this->connection->getQueryBuilder();
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)));
$query->execute();
}
public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
$query->execute();
foreach ($resource->getCollections() as $collection) {
$this->invalidateAccessCacheForCollectionByUser($collection, $user);
}
}
protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())))
->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
$query->execute();
}
public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void {
$query = $this->connection->getQueryBuilder();
$userId = $user instanceof IUser ? $user->getUID() : '';
$query->delete(self::TABLE_ACCESS_CACHE)
->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)))
->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
$query->execute();
}
/**
* @param string $provider
*/
public function registerResourceProvider(string $provider): void {
$this->providers[] = $provider;
}
/**
* Get the resource type of the provider
*
* @return string
* @since 16.0.0
*/
public function getType(): string {
return '';
}
/**
* Get the link to a resource
*
* @param IResource $resource
* @return string
* @since 16.0.0
*/
public function getLink(IResource $resource): string {
foreach ($this->getProviders() as $provider) {
if ($provider->getType() === $resource->getType()) {
try {
return $provider->getLink($resource);
} catch (ResourceException $e) {
}
}
}
return '';
}
}

View File

@ -0,0 +1,185 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Collaboration\Resources;
use OCP\Collaboration\Resources\ICollection;
use OCP\Collaboration\Resources\IManager;
use OCP\Collaboration\Resources\IResource;
use OCP\IDBConnection;
use OCP\IUser;
class Resource implements IResource {
/** @var IManager */
protected $manager;
/** @var IDBConnection */
protected $connection;
/** @var string */
protected $type;
/** @var string */
protected $id;
/** @var IUser|null */
protected $userForAccess;
/** @var bool|null */
protected $access;
/** @var string|null */
protected $name;
/** @var string|null */
protected $iconClass;
/** @var string|null */
protected $link;
public function __construct(
IManager $manager,
IDBConnection $connection,
string $type,
string $id,
?IUser $userForAccess = null,
?bool $access = null
) {
$this->manager = $manager;
$this->connection = $connection;
$this->type = $type;
$this->id = $id;
$this->userForAccess = $userForAccess;
$this->access = $access;
}
/**
* @return string
* @since 16.0.0
*/
public function getType(): string {
return $this->type;
}
/**
* @return string
* @since 16.0.0
*/
public function getId(): string {
return $this->id;
}
/**
* @return string
* @since 16.0.0
*/
public function getName(): string {
if ($this->name === null) {
$this->name = $this->manager->getName($this);
}
return $this->name;
}
/**
* @return string
* @since 16.0.0
*/
public function getIconClass(): string {
if ($this->iconClass === null) {
$this->iconClass = $this->manager->getIconClass($this);
}
return $this->iconClass;
}
public function getLink(): string {
if ($this->link === null) {
$this->link = $this->manager->getLink($this);
}
return $this->link;
}
/**
* Can a user/guest access the resource
*
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccess(?IUser $user): bool {
if ($user instanceof IUser) {
return $this->canUserAccess($user);
}
return $this->canGuestAccess();
}
protected function canUserAccess(IUser $user): bool {
if (\is_bool($this->access) && $this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
return $this->access;
}
$access = $this->manager->canAccessResource($this, $user);
if ($this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
$this->access = $access;
}
return $access;
}
protected function canGuestAccess(): bool {
if (\is_bool($this->access) && !$this->userForAccess instanceof IUser) {
return $this->access;
}
$access = $this->manager->canAccessResource($this, null);
if (!$this->userForAccess instanceof IUser) {
$this->access = $access;
}
return $access;
}
/**
* @return ICollection[]
* @since 16.0.0
*/
public function getCollections(): array {
$collections = [];
$query = $this->connection->getQueryBuilder();
$query->select('collection_id')
->from('collres_resources')
->where($query->expr()->eq('resource_type', $query->createNamedParameter($this->getType())))
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($this->getId())));
$result = $query->execute();
while ($row = $result->fetch()) {
$collections[] = $this->manager->getCollection((int) $row['collection_id']);
}
$result->closeCursor();
return $collections;
}
}

View File

@ -1299,7 +1299,7 @@ class View {
if ($owner instanceof IUser) {
return $owner;
} else {
return new User($ownerId, null);
return new User($ownerId, null, \OC::$server->getEventDispatcher());
}
}
@ -1381,8 +1381,12 @@ class View {
if ($mount instanceof MoveableMount && $internalPath === '') {
$data['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
}
$owner = $this->getUserObjectForOwner($storage->getOwner($internalPath));
$ownerId = $storage->getOwner($internalPath);
$owner = null;
if ($ownerId !== null) {
// ownerId might be null if files are accessed with an access token without file system access
$owner = $this->getUserObjectForOwner($ownerId);
}
$info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner);
if ($data and isset($data['fileid'])) {

View File

@ -31,55 +31,50 @@
namespace OC\Group;
use OCP\Group\Backend\IHideFromCollaborationBackend;
use OC\Hooks\PublicEmitter;
use OCP\GroupInterface;
use OCP\IGroup;
use OCP\IUser;
use OCP\Group\Backend\ICountDisabledInGroup;
use OCP\IUserManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
class Group implements IGroup {
/** @var null|string */
protected $displayName;
/**
* @var string $id
*/
/** @var string */
private $gid;
/**
* @var \OC\User\User[] $users
*/
/** @var \OC\User\User[] */
private $users = array();
/**
* @var bool $usersLoaded
*/
/** @var bool */
private $usersLoaded;
/**
* @var \OC\Group\Backend[]|\OC\Group\Database[] $backend
*/
/** @var Backend[] */
private $backends;
/**
* @var \OC\Hooks\PublicEmitter $emitter
*/
/** @var EventDispatcherInterface */
private $dispatcher;
/** @var \OC\User\Manager|IUserManager */
private $userManager;
/** @var PublicEmitter */
private $emitter;
/**
* @var \OC\User\Manager $userManager
*/
private $userManager;
/**
* @param string $gid
* @param \OC\Group\Backend[] $backends
* @param \OC\User\Manager $userManager
* @param \OC\Hooks\PublicEmitter $emitter
* @param Backend[] $backends
* @param EventDispatcherInterface $dispatcher
* @param IUserManager $userManager
* @param PublicEmitter $emitter
* @param string $displayName
*/
public function __construct($gid, $backends, $userManager, $emitter = null, $displayName = null) {
public function __construct(string $gid, array $backends, EventDispatcherInterface $dispatcher, IUserManager $userManager, PublicEmitter $emitter = null, ?string $displayName = null) {
$this->gid = $gid;
$this->backends = $backends;
$this->dispatcher = $dispatcher;
$this->userManager = $userManager;
$this->emitter = $emitter;
$this->displayName = $displayName;
@ -151,6 +146,10 @@ class Group implements IGroup {
return;
}
$this->dispatcher->dispatch(IGroup::class . '::preAddUser', new GenericEvent($this, [
'user' => $user,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'preAddUser', array($this, $user));
}
@ -160,6 +159,11 @@ class Group implements IGroup {
if ($this->users) {
$this->users[$user->getUID()] = $user;
}
$this->dispatcher->dispatch(IGroup::class . '::postAddUser', new GenericEvent($this, [
'user' => $user,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'postAddUser', array($this, $user));
}
@ -175,6 +179,9 @@ class Group implements IGroup {
*/
public function removeUser($user) {
$result = false;
$this->dispatcher->dispatch(IGroup::class . '::preRemoveUser', new GenericEvent($this, [
'user' => $user,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'preRemoveUser', array($this, $user));
}
@ -185,6 +192,9 @@ class Group implements IGroup {
}
}
if ($result) {
$this->dispatcher->dispatch(IGroup::class . '::postRemoveUser', new GenericEvent($this, [
'user' => $user,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'postRemoveUser', array($this, $user));
}
@ -292,6 +302,7 @@ class Group implements IGroup {
}
$result = false;
$this->dispatcher->dispatch(IGroup::class . '::preDelete', new GenericEvent($this));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'preDelete', array($this));
}
@ -301,8 +312,11 @@ class Group implements IGroup {
$backend->deleteGroup($this->gid);
}
}
if ($result and $this->emitter) {
$this->emitter->emit('\OC\Group', 'postDelete', array($this));
if ($result) {
$this->dispatcher->dispatch(IGroup::class . '::postDelete', new GenericEvent($this));
if ($this->emitter) {
$this->emitter->emit('\OC\Group', 'postDelete', array($this));
}
}
return $result;
}

View File

@ -44,6 +44,7 @@ use OCP\IGroup;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUser;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class Manager
@ -61,39 +62,37 @@ use OCP\IUser;
* @package OC\Group
*/
class Manager extends PublicEmitter implements IGroupManager {
/**
* @var GroupInterface[] $backends
*/
private $backends = array();
/** @var GroupInterface[] */
private $backends = [];
/**
* @var \OC\User\Manager $userManager
*/
/** @var \OC\User\Manager */
private $userManager;
/** @var EventDispatcherInterface */
private $dispatcher;
/** @var ILogger */
private $logger;
/**
* @var \OC\Group\Group[]
*/
private $cachedGroups = array();
/** @var \OC\Group\Group[] */
private $cachedGroups = [];
/**
* @var \OC\Group\Group[]
*/
private $cachedUserGroups = array();
/** @var \OC\Group\Group[] */
private $cachedUserGroups = [];
/** @var \OC\SubAdmin */
private $subAdmin = null;
/** @var ILogger */
private $logger;
/**
* @param \OC\User\Manager $userManager
* @param EventDispatcherInterface $dispatcher
* @param ILogger $logger
*/
public function __construct(\OC\User\Manager $userManager, ILogger $logger) {
public function __construct(\OC\User\Manager $userManager,
EventDispatcherInterface $dispatcher,
ILogger $logger) {
$this->userManager = $userManager;
$this->dispatcher = $dispatcher;
$this->logger = $logger;
$cachedGroups = & $this->cachedGroups;
$cachedUserGroups = & $this->cachedUserGroups;
$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
@ -101,19 +100,19 @@ class Manager extends PublicEmitter implements IGroupManager {
* @var \OC\Group\Group $group
*/
unset($cachedGroups[$group->getGID()]);
$cachedUserGroups = array();
$cachedUserGroups = [];
});
$this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) {
/**
* @var \OC\Group\Group $group
*/
$cachedUserGroups = array();
$cachedUserGroups = [];
});
$this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) {
/**
* @var \OC\Group\Group $group
*/
$cachedUserGroups = array();
$cachedUserGroups = [];
});
}
@ -144,7 +143,7 @@ class Manager extends PublicEmitter implements IGroupManager {
}
public function clearBackends() {
$this->backends = array();
$this->backends = [];
$this->clearCaches();
}
@ -158,8 +157,8 @@ class Manager extends PublicEmitter implements IGroupManager {
protected function clearCaches() {
$this->cachedGroups = array();
$this->cachedUserGroups = array();
$this->cachedGroups = [];
$this->cachedUserGroups = [];
}
/**
@ -179,7 +178,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @return \OCP\IGroup
*/
protected function getGroupObject($gid, $displayName = null) {
$backends = array();
$backends = [];
foreach ($this->backends as $backend) {
if ($backend->implementsActions(\OC\Group\Backend::GROUP_DETAILS)) {
$groupData = $backend->getGroupDetails($gid);
@ -197,7 +196,7 @@ class Manager extends PublicEmitter implements IGroupManager {
if (count($backends) === 0) {
return null;
}
$this->cachedGroups[$gid] = new Group($gid, $backends, $this->userManager, $this, $displayName);
$this->cachedGroups[$gid] = new Group($gid, $backends, $this->dispatcher, $this->userManager, $this, $displayName);
return $this->cachedGroups[$gid];
}
@ -239,7 +238,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @return \OC\Group\Group[]
*/
public function search($search, $limit = null, $offset = null) {
$groups = array();
$groups = [];
foreach ($this->backends as $backend) {
$groupIds = $backend->getGroups($search, $limit, $offset);
foreach ($groupIds as $groupId) {
@ -276,7 +275,7 @@ class Manager extends PublicEmitter implements IGroupManager {
if (isset($this->cachedUserGroups[$uid])) {
return $this->cachedUserGroups[$uid];
}
$groups = array();
$groups = [];
foreach ($this->backends as $backend) {
$groupIds = $backend->getUserGroups($uid);
if (is_array($groupIds)) {
@ -351,11 +350,11 @@ class Manager extends PublicEmitter implements IGroupManager {
public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
$group = $this->get($gid);
if(is_null($group)) {
return array();
return [];
}
$search = trim($search);
$groupUsers = array();
$groupUsers = [];
if(!empty($search)) {
// only user backends have the capability to do a complex search for users
@ -384,7 +383,7 @@ class Manager extends PublicEmitter implements IGroupManager {
$groupUsers = $group->searchUsers('', $limit, $offset);
}
$matchingUsers = array();
$matchingUsers = [];
foreach($groupUsers as $groupUser) {
$matchingUsers[$groupUser->getUID()] = $groupUser->getDisplayName();
}

View File

@ -316,14 +316,13 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias('LazyRootFolder', \OCP\Files\IRootFolder::class);
$this->registerService(\OC\User\Manager::class, function (Server $c) {
$config = $c->getConfig();
return new \OC\User\Manager($config);
return new \OC\User\Manager($c->getConfig(), $c->getEventDispatcher());
});
$this->registerAlias('UserManager', \OC\User\Manager::class);
$this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
$this->registerService(\OCP\IGroupManager::class, function (Server $c) {
$groupManager = new \OC\Group\Manager($this->getUserManager(), $this->getLogger());
$groupManager = new \OC\Group\Manager($this->getUserManager(), $c->getEventDispatcher(), $this->getLogger());
$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
\OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
});
@ -1095,6 +1094,8 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class);
$this->registerAlias(\OCP\Collaboration\Resources\IManager::class, \OC\Collaboration\Resources\Manager::class);
$this->registerService('SettingsManager', function (Server $c) {
$manager = new \OC\Settings\Manager(
$c->getLogger(),

View File

@ -39,6 +39,7 @@ use OCP\IUserBackend;
use OCP\IUserManager;
use OCP\IConfig;
use OCP\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class Manager
@ -68,16 +69,14 @@ class Manager extends PublicEmitter implements IUserManager {
*/
private $cachedUsers = array();
/**
* @var \OCP\IConfig $config
*/
/** @var IConfig */
private $config;
/** @var EventDispatcherInterface */
private $dispatcher;
/**
* @param \OCP\IConfig $config
*/
public function __construct(IConfig $config) {
public function __construct(IConfig $config, EventDispatcherInterface $dispatcher) {
$this->config = $config;
$this->dispatcher = $dispatcher;
$cachedUsers = &$this->cachedUsers;
$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
/** @var \OC\User\User $user */
@ -156,7 +155,7 @@ class Manager extends PublicEmitter implements IUserManager {
return $this->cachedUsers[$uid];
}
$user = new User($uid, $backend, $this, $this->config);
$user = new User($uid, $backend, $this->dispatcher, $this, $this->config);
if ($cacheUser) {
$this->cachedUsers[$uid] = $user;
}

View File

@ -42,30 +42,34 @@ use OCP\IUser;
use OCP\IConfig;
use OCP\UserInterface;
use \OCP\IUserBackend;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
class User implements IUser {
/** @var string $uid */
/** @var string */
private $uid;
/** @var string $displayName */
/** @var string */
private $displayName;
/** @var UserInterface $backend */
/** @var UserInterface|null */
private $backend;
/** @var EventDispatcherInterface */
private $dispatcher;
/** @var bool $enabled */
/** @var bool */
private $enabled;
/** @var Emitter|Manager $emitter */
/** @var Emitter|Manager */
private $emitter;
/** @var string $home */
/** @var string */
private $home;
/** @var int $lastLogin */
/** @var int */
private $lastLogin;
/** @var \OCP\IConfig $config */
/** @var \OCP\IConfig */
private $config;
/** @var IAvatarManager */
@ -74,16 +78,10 @@ class User implements IUser {
/** @var IURLGenerator */
private $urlGenerator;
/**
* @param string $uid
* @param UserInterface $backend
* @param \OC\Hooks\Emitter $emitter
* @param IConfig|null $config
* @param IURLGenerator $urlGenerator
*/
public function __construct($uid, $backend, $emitter = null, IConfig $config = null, $urlGenerator = null) {
public function __construct(string $uid, ?UserInterface $backend, EventDispatcherInterface $dispatcher, $emitter = null, IConfig $config = null, $urlGenerator = null) {
$this->uid = $uid;
$this->backend = $backend;
$this->dispatcher = $dispatcher;
$this->emitter = $emitter;
if(is_null($config)) {
$config = \OC::$server->getConfig();
@ -115,7 +113,7 @@ class User implements IUser {
public function getDisplayName() {
if (!isset($this->displayName)) {
$displayName = '';
if ($this->backend and $this->backend->implementsActions(Backend::GET_DISPLAYNAME)) {
if ($this->backend && $this->backend->implementsActions(Backend::GET_DISPLAYNAME)) {
// get display name and strip whitespace from the beginning and end of it
$backendDisplayName = $this->backend->getDisplayName($this->uid);
if (is_string($backendDisplayName)) {
@ -199,6 +197,7 @@ class User implements IUser {
* @return bool
*/
public function delete() {
$this->dispatcher->dispatch(IUser::class . '::preDelete', new GenericEvent($this));
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'preDelete', array($this));
}
@ -243,6 +242,7 @@ class User implements IUser {
$accountManager = \OC::$server->query(AccountManager::class);
$accountManager->deleteUser($this);
$this->dispatcher->dispatch(IUser::class . '::postDelete', new GenericEvent($this));
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'postDelete', array($this));
}
@ -258,11 +258,19 @@ class User implements IUser {
* @return bool
*/
public function setPassword($password, $recoveryPassword = null) {
$this->dispatcher->dispatch(IUser::class . '::preSetPassword', new GenericEvent($this, [
'password' => $password,
'recoveryPassword' => $recoveryPassword,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'preSetPassword', array($this, $password, $recoveryPassword));
}
if ($this->backend->implementsActions(Backend::SET_PASSWORD)) {
$result = $this->backend->setPassword($this->uid, $password);
$this->dispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [
'password' => $password,
'recoveryPassword' => $recoveryPassword,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'postSetPassword', array($this, $password, $recoveryPassword));
}
@ -455,6 +463,11 @@ class User implements IUser {
}
public function triggerChange($feature, $value = null, $oldValue = null) {
$this->dispatcher->dispatch(IUser::class . '::changeUser', new GenericEvent($this, [
'feature' => $feature,
'value' => $value,
'oldValue' => $oldValue,
]));
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'changeUser', array($this, $feature, $value, $oldValue));
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
/**
* @since 16.0.0
*/
class CollectionException extends \RuntimeException {
}

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
use OCP\IUser;
/**
* @since 16.0.0
*/
interface ICollection {
/**
* @return int
* @since 16.0.0
*/
public function getId(): int;
/**
* @return string
* @since 16.0.0
*/
public function getName(): string;
/**
* @param string $name
* @since 16.0.0
*/
public function setName(string $name): void;
/**
* @return IResource[]
* @since 16.0.0
*/
public function getResources(): array;
/**
* Adds a resource to a collection
*
* @param IResource $resource
* @throws ResourceException when the resource is already part of the collection
* @since 16.0.0
*/
public function addResource(IResource $resource): void;
/**
* Removes a resource from a collection
*
* @param IResource $resource
* @since 16.0.0
*/
public function removeResource(IResource $resource): void;
/**
* Can a user/guest access the collection
*
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccess(?IUser $user): bool;
}

View File

@ -0,0 +1,121 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
use OCP\IUser;
/**
* @since 16.0.0
*/
interface IManager extends IProvider {
/**
* @param int $id
* @return ICollection
* @throws CollectionException when the collection could not be found
* @since 16.0.0
*/
public function getCollection(int $id): ICollection;
/**
* @param int $id
* @param IUser|null $user
* @return ICollection
* @throws CollectionException when the collection could not be found
* @since 16.0.0
*/
public function getCollectionForUser(int $id, ?IUser $user): ICollection;
/**
* @param string $name
* @return ICollection
* @since 16.0.0
*/
public function newCollection(string $name): ICollection;
/**
* Can a user/guest access the collection
*
* @param ICollection $collection
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccessCollection(ICollection $collection, ?IUser $user): bool;
/**
* @param IUser|null $user
* @since 16.0.0
*/
public function invalidateAccessCacheForUser(?IUser $user): void;
/**
* @param IResource $resource
* @since 16.0.0
*/
public function invalidateAccessCacheForResource(IResource $resource): void;
/**
* @param IResource $resource
* @param IUser|null $user
* @since 16.0.0
*/
public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void;
/**
* @param IProvider $provider
* @since 16.0.0
*/
public function invalidateAccessCacheForProvider(IProvider $provider): void;
/**
* @param IProvider $provider
* @param IUser|null $user
* @since 16.0.0
*/
public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void;
/**
* @param string $type
* @param string $id
* @return IResource
* @since 16.0.0
*/
public function createResource(string $type, string $id): IResource;
/**
* @param string $type
* @param string $id
* @param IUser|null $user
* @return IResource
* @throws ResourceException
* @since 16.0.0
*/
public function getResourceForUser(string $type, string $id, ?IUser $user): IResource;
/**
* @param string $provider
* @since 16.0.0
*/
public function registerResourceProvider(string $provider): void;
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
use OCP\IUser;
/**
* @since 16.0.0
*/
interface IProvider {
/**
* Get the resource type of the provider
*
* @return string
* @since 16.0.0
*/
public function getType(): string;
/**
* Get the display name of a resource
*
* @param IResource $resource
* @return string
* @since 16.0.0
*/
public function getName(IResource $resource): string;
/**
* Get the icon class of a resource
*
* @param IResource $resource
* @return string
* @since 16.0.0
*/
public function getIconClass(IResource $resource): string;
/**
* Get the link to a resource
*
* @param IResource $resource
* @return string
* @since 16.0.0
*/
public function getLink(IResource $resource): string;
/**
* Can a user/guest access the collection
*
* @param IResource $resource
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccessResource(IResource $resource, ?IUser $user): bool;
}

View File

@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
use OCP\IUser;
/**
* @since 16.0.0
*/
interface IResource {
/**
* @return string
* @since 16.0.0
*/
public function getType(): string;
/**
* @return string
* @since 16.0.0
*/
public function getId(): string;
/**
* @return string
* @since 16.0.0
*/
public function getName(): string;
/**
* @return string
* @since 16.0.0
*/
public function getIconClass(): string;
/**
* @return string
* @since 16.0.0
*/
public function getLink(): string;
/**
* Can a user/guest access the resource
*
* @param IUser|null $user
* @return bool
* @since 16.0.0
*/
public function canAccess(?IUser $user): bool;
/**
* @return ICollection[]
* @since 16.0.0
*/
public function getCollections(): array;
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @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 OCP\Collaboration\Resources;
/**
* @since 16.0.0
*/
class ResourceException extends \RuntimeException {
}

1808
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@
"nextcloud-axios": "^0.1.3",
"nextcloud-password-confirmation": "^0.4.1",
"nextcloud-vue": "^0.8.0",
"nextcloud-vue-collections": "^0.1.2",
"snap.js": "^2.0.9",
"strengthify": "git+https://github.com/MorrisJobke/strengthify.git",
"underscore": "^1.9.1",
@ -63,6 +64,7 @@
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.3.4",
"babel-loader": "^8.0.5",
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
"css-loader": "^2.1.0",
"exports-loader": "^0.7.0",
"file-loader": "^3.0.1",

View File

@ -54,7 +54,7 @@ module.exports = function(config) {
// up with the global namespace/classes/state
'apps/files_sharing/js/app.js',
'apps/files_sharing/js/sharedfilelist.js',
'apps/files_sharing/js/additionalScripts.js',
'apps/files_sharing/js/dist/additionalScripts.js',
'apps/files_sharing/js/public.js',
'apps/files_sharing/js/files_drop.js',
'apps/files_sharing/js/templates.js',

View File

@ -17,7 +17,9 @@ use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
use OCP\IAppConfig;
use OCP\IConfig;
@ -144,10 +146,14 @@ class AppManagerTest extends TestCase {
}
public function testEnableAppForGroups() {
$groups = array(
new Group('group1', array(), null),
new Group('group2', array(), null)
);
$group1 = $this->createMock(IGroup::class);
$group1->method('getGID')
->willReturn('group1');
$group2 = $this->createMock(IGroup::class);
$group2->method('getGID')
->willReturn('group2');
$groups = [$group1, $group2];
$this->expectClearCache();
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
@ -187,10 +193,14 @@ class AppManagerTest extends TestCase {
* @param array $appInfo
*/
public function testEnableAppForGroupsAllowedTypes(array $appInfo) {
$groups = array(
new Group('group1', array(), null),
new Group('group2', array(), null)
);
$group1 = $this->createMock(IGroup::class);
$group1->method('getGID')
->willReturn('group1');
$group2 = $this->createMock(IGroup::class);
$group2->method('getGID')
->willReturn('group2');
$groups = [$group1, $group2];
$this->expectClearCache();
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
@ -237,10 +247,14 @@ class AppManagerTest extends TestCase {
* @expectedExceptionMessage test can't be enabled for groups.
*/
public function testEnableAppForGroupsForbiddenTypes($type) {
$groups = array(
new Group('group1', array(), null),
new Group('group2', array(), null)
);
$group1 = $this->createMock(IGroup::class);
$group1->method('getGID')
->willReturn('group1');
$group2 = $this->createMock(IGroup::class);
$group2->method('getGID')
->willReturn('group2');
$groups = [$group1, $group2];
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
@ -284,10 +298,11 @@ class AppManagerTest extends TestCase {
}
private function newUser($uid) {
$config = $this->createMock(IConfig::class);
$urlgenerator = $this->createMock(IURLGenerator::class);
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn($uid);
return new User($uid, null, null, $config, $urlgenerator);
return $user;
}
public function testIsEnabledForUserEnabled() {

View File

@ -332,7 +332,7 @@ class CacheTest extends \Test\TestCase {
$userId = $this->getUniqueId('user');
\OC::$server->getUserManager()->createUser($userId, $userId);
$this->loginAsUser($userId);
$user = new \OC\User\User($userId, null);
$user = new \OC\User\User($userId, null, \OC::$server->getEventDispatcher());
$file1 = 'folder';
$file2 = 'folder/foobar';
@ -402,7 +402,7 @@ class CacheTest extends \Test\TestCase {
$userId = static::getUniqueID('user');
\OC::$server->getUserManager()->createUser($userId, $userId);
static::loginAsUser($userId);
$user = new \OC\User\User($userId, null);
$user = new \OC\User\User($userId, null, \OC::$server->getEventDispatcher());
$file1 = 'folder';
$file2 = 'folder/foobar';

View File

@ -17,6 +17,7 @@ use OC\Files\Storage\Storage;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IUserManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
use Test\Util\User\Dummy;
@ -44,7 +45,7 @@ class UserMountCacheTest extends TestCase {
public function setUp() {
$this->fileIds = [];
$this->connection = \OC::$server->getDatabaseConnection();
$this->userManager = new Manager($this->createMock(IConfig::class));
$this->userManager = new Manager($this->createMock(IConfig::class), $this->createMock(EventDispatcherInterface::class));
$userBackend = new Dummy();
$userBackend->createUser('u1', '');
$userBackend->createUser('u2', '');

View File

@ -14,6 +14,7 @@ use OC\Files\Storage\Home;
use OC\Files\Storage\Temporary;
use OC\User\User;
use OCP\IConfig;
use OCP\IUser;
use Test\TestCase;
use Test\Traits\UserTrait;
@ -29,9 +30,15 @@ class FileInfoTest extends TestCase {
}
public function testIsMountedHomeStorage() {
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('foo');
$user->method('getHome')
->willReturn('foo');
$fileInfo = new FileInfo(
'',
new Home(['user' => new User('foo', $this->userBackend, null, $this->config)]),
new Home(['user' => $user]),
'', [], null);
$this->assertFalse($fileInfo->isMounted());
}

View File

@ -45,7 +45,7 @@ class IntegrationTest extends \Test\TestCase {
\OC_Hook::clear('OC_Filesystem');
$user = new User($this->getUniqueID('user'), new \Test\Util\User\Dummy);
$user = new User($this->getUniqueID('user'), new \Test\Util\User\Dummy, \OC::$server->getEventDispatcher());
$this->loginAsUser($user->getUID());
$this->view = new View();

View File

@ -18,6 +18,7 @@ use OCP\Files\Storage;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Files\NotFoundException;
@ -45,14 +46,7 @@ abstract class NodeTest extends \Test\TestCase {
protected function setUp() {
parent::setUp();
$config = $this->getMockBuilder(IConfig::class)
->disableOriginalConstructor()
->getMock();
$urlGenerator = $this->getMockBuilder(IURLGenerator
::class)
->disableOriginalConstructor()
->getMock();
$this->user = new \OC\User\User('', new \Test\Util\User\Dummy, null, $config, $urlGenerator);
$this->user = $this->createMock(IUser::class);
$this->manager = $this->getMockBuilder(Manager::class)
->disableOriginalConstructor()
->getMock();

View File

@ -39,14 +39,7 @@ class RootTest extends \Test\TestCase {
protected function setUp() {
parent::setUp();
$config = $this->getMockBuilder(IConfig::class)
->disableOriginalConstructor()
->getMock();
$urlgenerator = $this->getMockBuilder(IURLGenerator::class)
->disableOriginalConstructor()
->getMock();
$this->user = new \OC\User\User('', new \Test\Util\User\Dummy, null, $config, $urlgenerator);
$this->user = $this->createMock(IUser::class);
$this->manager = $this->getMockBuilder(Manager::class)
->disableOriginalConstructor()
->getMock();

View File

@ -18,6 +18,7 @@ use OCP\Files\Cache\ICache;
use OCP\Files\Mount\IMountPoint;
use OCP\IConfig;
use OCP\ILogger;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\Files\Storage\Storage;
class EncryptionTest extends Storage {
@ -130,7 +131,7 @@ class EncryptionTest extends Storage {
$this->util = $this->getMockBuilder('\OC\Encryption\Util')
->setMethods(['getUidAndFilename', 'isFile', 'isExcluded'])
->setConstructorArgs([new View(), new Manager($this->config), $this->groupManager, $this->config, $this->arrayCache])
->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(EventDispatcherInterface::class)), $this->groupManager, $this->config, $this->arrayCache])
->getMock();
$this->util->expects($this->any())
->method('getUidAndFilename')
@ -558,7 +559,7 @@ class EncryptionTest extends Storage {
->setConstructorArgs(
[
new View(),
new Manager($this->config),
new Manager($this->config, $this->createMock(EventDispatcherInterface::class)),
$this->groupManager,
$this->config,
$this->arrayCache
@ -627,7 +628,7 @@ class EncryptionTest extends Storage {
->willReturn($exists);
$util = $this->getMockBuilder('\OC\Encryption\Util')
->setConstructorArgs([new View(), new Manager($this->config), $this->groupManager, $this->config, $this->arrayCache])
->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(EventDispatcherInterface::class)), $this->groupManager, $this->config, $this->arrayCache])
->getMock();
$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')

View File

@ -7,6 +7,7 @@ use OC\Files\View;
use OC\Memcache\ArrayCache;
use OCP\Files\Cache\ICache;
use OCP\IConfig;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class EncryptionTest extends \Test\TestCase {
@ -47,7 +48,7 @@ class EncryptionTest extends \Test\TestCase {
$file->expects($this->any())->method('getAccessList')->willReturn([]);
$util = $this->getMockBuilder('\OC\Encryption\Util')
->setMethods(['getUidAndFilename'])
->setConstructorArgs([new View(), new \OC\User\Manager($config), $groupManager, $config, $arrayCache])
->setConstructorArgs([new View(), new \OC\User\Manager($config, $this->createMock(EventDispatcherInterface::class)), $groupManager, $config, $arrayCache])
->getMock();
$util->expects($this->any())
->method('getUidAndFilename')

View File

@ -12,8 +12,19 @@ namespace Test\Group;
use OC\User\User;
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\IUser;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class GroupTest extends \Test\TestCase {
/** @var EventDispatcherInterface|MockObject */
protected $dispatcher;
public function setUp() {
parent::setUp();
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
}
/**
* @param string $uid
@ -21,14 +32,13 @@ class GroupTest extends \Test\TestCase {
* @return User
*/
private function newUser($uid, \OC\User\Backend $backend) {
$config = $this->getMockBuilder(IConfig::class)
->disableOriginalConstructor()
->getMock();
$urlgenerator = $this->getMockBuilder(IURLGenerator::class)
->disableOriginalConstructor()
->getMock();
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn($uid);
$user->method('getBackend')
->willReturn($backend);
return new User($uid, $backend, null, $config, $urlgenerator);
return $user;
}
/**
@ -59,7 +69,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('usersInGroup')
@ -83,7 +93,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('usersInGroup')
@ -114,7 +124,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder('\OC\User\Backend')
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('inGroup')
@ -135,7 +145,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder(\OC\User\Backend::class)
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('inGroup')
@ -158,7 +168,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder('\OC\User\Backend')
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('inGroup')
@ -183,7 +193,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder('\OC\User\Backend')
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('inGroup')
@ -207,7 +217,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder('\OC\User\Backend')
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('inGroup')
@ -232,7 +242,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder(\OC\User\Backend::class)
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('inGroup')
@ -259,7 +269,7 @@ class GroupTest extends \Test\TestCase {
$userBackend = $this->getMockBuilder('\OC\User\Backend')
->disableOriginalConstructor()
->getMock();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('inGroup')
@ -293,7 +303,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('usersInGroup')
@ -315,7 +325,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('usersInGroup')
@ -338,7 +348,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('usersInGroup')
@ -360,7 +370,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('usersInGroup')
@ -385,7 +395,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1), $userManager);
$group = new \OC\Group\Group('group1', array($backend1), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('countUsersInGroup')
@ -409,7 +419,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager);
$group = new \OC\Group\Group('group1', array($backend1, $backend2), $this->dispatcher, $userManager);
$backend1->expects($this->once())
->method('countUsersInGroup')
@ -437,7 +447,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend1), $userManager);
$group = new \OC\Group\Group('group1', array($backend1), $this->dispatcher, $userManager);
$backend1->expects($this->never())
->method('countUsersInGroup');
@ -455,7 +465,7 @@ class GroupTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
$userManager = $this->getUserManager();
$group = new \OC\Group\Group('group1', array($backend), $userManager);
$group = new \OC\Group\Group('group1', array($backend), $this->dispatcher, $userManager);
$backend->expects($this->once())
->method('deleteGroup')

View File

@ -27,18 +27,23 @@ use OC\User\Manager;
use OCP\ILogger;
use OCP\IUser;
use OCP\GroupInterface;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
class ManagerTest extends TestCase {
/** @var Manager|\PHPUnit_Framework_MockObject_MockObject $userManager */
/** @var Manager|MockObject */
protected $userManager;
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject $userManager */
/** @var EventDispatcherInterface|MockObject */
protected $dispatcher;
/** @var ILogger|MockObject */
protected $logger;
protected function setUp() {
parent::setUp();
$this->userManager = $this->createMock(Manager::class);
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
$this->logger = $this->createMock(ILogger::class);
}
@ -101,7 +106,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$group = $manager->get('group1');
@ -110,7 +115,7 @@ class ManagerTest extends TestCase {
}
public function testGetNoBackend() {
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$this->assertNull($manager->get('group1'));
}
@ -125,7 +130,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(false));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$this->assertNull($manager->get('group1'));
@ -135,7 +140,7 @@ class ManagerTest extends TestCase {
$backend = new \Test\Util\Group\Dummy();
$backend->createGroup('group1');
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$group = $manager->get('group1');
@ -162,7 +167,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
@ -187,7 +192,7 @@ class ManagerTest extends TestCase {
$backendGroupCreated = true;
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$group = $manager->createGroup('group1');
@ -204,7 +209,7 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('createGroup');
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$group = $manager->createGroup('group1');
@ -225,7 +230,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$groups = $manager->search('1');
@ -259,7 +264,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
@ -296,7 +301,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
@ -323,7 +328,7 @@ class ManagerTest extends TestCase {
/** @var \OC\User\Manager $userManager */
$userManager = $this->createMock(Manager::class);
$manager = new \OC\Group\Manager($userManager, $this->logger);
$manager = new \OC\Group\Manager($userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$groups = $manager->search('1');
@ -344,7 +349,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$groups = $manager->getUserGroups($this->getTestUser('user1'));
@ -391,7 +396,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(false));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
/** @var \OC\User\User|\PHPUnit_Framework_MockObject_MockObject $user */
@ -417,7 +422,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$this->assertTrue($manager->isInGroup('user1', 'group1'));
@ -436,7 +441,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$this->assertTrue($manager->isAdmin('user1'));
@ -455,7 +460,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$this->assertFalse($manager->isAdmin('user1'));
@ -486,7 +491,7 @@ class ManagerTest extends TestCase {
->method('groupExists')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend1);
$manager->addBackend($backend2);
@ -545,7 +550,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3');
@ -605,7 +610,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3', 1);
@ -669,7 +674,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', 'user3', 1, 1);
@ -709,7 +714,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '');
@ -748,7 +753,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '', 1);
@ -787,7 +792,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$users = $manager->displayNamesInGroup('testgroup', '', 1, 1);
@ -815,7 +820,7 @@ class ManagerTest extends TestCase {
->with('group1')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
// prime cache
@ -858,7 +863,7 @@ class ManagerTest extends TestCase {
->method('removeFromGroup')
->will($this->returnValue(true));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
// prime cache
@ -888,7 +893,7 @@ class ManagerTest extends TestCase {
->with('user1')
->will($this->returnValue(null));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
$groups = $manager->getUserIdGroups('user1');
@ -914,7 +919,7 @@ class ManagerTest extends TestCase {
['group2', ['gid' => 'group2']],
]));
$manager = new \OC\Group\Manager($this->userManager, $this->logger);
$manager = new \OC\Group\Manager($this->userManager, $this->dispatcher, $this->logger);
$manager->addBackend($backend);
// group with display name

View File

@ -21,6 +21,7 @@
*/
namespace Test;
use OCP\IUser;
use OCP\IUserSession;
/**
@ -49,7 +50,9 @@ class TagsTest extends \Test\TestCase {
$userId = $this->getUniqueID('user_');
\OC::$server->getUserManager()->createUser($userId, 'pass');
\OC_User::setUserId($userId);
$this->user = new \OC\User\User($userId, null);
$this->user = $this->createMock(IUser::class);
$this->user->method('getUID')
->willReturn($userId);
$this->userSession = $this->createMock(IUserSession::class);
$this->userSession
->expects($this->any())
@ -292,14 +295,19 @@ class TagsTest extends \Test\TestCase {
$tagger = $this->tagMgr->load('test');
$tagger->tagAs(1, $testTag);
$otherUserId = $this->getUniqueID('user2_');
$otherUser = $this->createMock(IUser::class);
$otherUser->method('getUID')
->willReturn($otherUserId);
\OC::$server->getUserManager()->createUser($otherUserId, 'pass');
\OC_User::setUserId($otherUserId);
$otherUserSession = $this->createMock(IUserSession::class);
$otherUserSession
->expects($this->any())
->method('getUser')
->will($this->returnValue(new \OC\User\User($otherUserId, null)));
->willReturn($otherUser);
$otherTagMgr = new \OC\TagManager($this->tagMapper, $otherUserSession);
$otherTagger = $otherTagMgr->load('test');

View File

@ -22,7 +22,7 @@
namespace Test\User;
use OC\HintException;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use OC\User\User;
@ -34,7 +34,7 @@ use OC\User\User;
class DatabaseTest extends Backend {
/** @var array */
private $users;
/** @var EventDispatcher | \PHPUnit_Framework_MockObject_MockObject */
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
private $eventDispatcher;
public function getUser() {
@ -46,7 +46,7 @@ class DatabaseTest extends Backend {
protected function setUp() {
parent::setUp();
$this->eventDispatcher = $this->createMock(EventDispatcher::class);
$this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$this->backend=new \OC\User\Database($this->eventDispatcher);
}
@ -124,8 +124,8 @@ class DatabaseTest extends Backend {
$user2 = $this->getUser();
$this->backend->createUser($user2, 'pass1');
$user1Obj = new User($user1, $this->backend);
$user2Obj = new User($user2, $this->backend);
$user1Obj = new User($user1, $this->backend, $this->eventDispatcher);
$user2Obj = new User($user2, $this->backend, $this->eventDispatcher);
$emailAddr1 = "$user1@nextcloud.com";
$emailAddr2 = "$user2@nextcloud.com";

View File

@ -13,6 +13,7 @@ use OC\User\Database;
use OC\User\Manager;
use OCP\IConfig;
use OCP\IUser;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
/**
@ -26,16 +27,19 @@ class ManagerTest extends TestCase {
/** @var IConfig */
private $config;
/** @var EventDispatcherInterface */
private $dispatcher;
public function setUp() {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
}
public function testGetBackends() {
$userDummyBackend = $this->createMock(\Test\Util\User\Dummy::class);
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($userDummyBackend);
$this->assertEquals([$userDummyBackend], $manager->getBackends());
$dummyDatabaseBackend = $this->createMock(Database::class);
@ -54,7 +58,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertTrue($manager->userExists('foo'));
@ -70,14 +74,14 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(false));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertFalse($manager->userExists('foo'));
}
public function testUserExistsNoBackends() {
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$this->assertFalse($manager->userExists('foo'));
}
@ -101,7 +105,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend1);
$manager->registerBackend($backend2);
@ -125,7 +129,7 @@ class ManagerTest extends TestCase {
$backend2->expects($this->never())
->method('userExists');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend1);
$manager->registerBackend($backend2);
@ -152,7 +156,7 @@ class ManagerTest extends TestCase {
}
}));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$user = $manager->checkPassword('foo', 'bar');
@ -171,7 +175,7 @@ class ManagerTest extends TestCase {
->method('implementsActions')
->will($this->returnValue(false));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertFalse($manager->checkPassword('foo', 'bar'));
@ -189,7 +193,7 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('loginName2UserName');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertEquals('foo', $manager->get('foo')->getUID());
@ -205,7 +209,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(false));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertEquals(null, $manager->get('foo'));
@ -223,7 +227,7 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('loginName2UserName');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertEquals('bLeNdEr', $manager->get('bLeNdEr')->getUID());
@ -241,7 +245,7 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('loginName2UserName');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$result = $manager->search('fo');
@ -275,7 +279,7 @@ class ManagerTest extends TestCase {
$backend2->expects($this->never())
->method('loginName2UserName');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend1);
$manager->registerBackend($backend2);
@ -329,7 +333,7 @@ class ManagerTest extends TestCase {
->willReturn(true);
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->expectException(\InvalidArgumentException::class, $exception);
@ -356,7 +360,7 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('loginName2UserName');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$user = $manager->createUser('foo', 'bar');
@ -383,7 +387,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$manager->createUser('foo', 'bar');
@ -404,14 +408,14 @@ class ManagerTest extends TestCase {
$backend->expects($this->never())
->method('userExists');
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$this->assertFalse($manager->createUser('foo', 'bar'));
}
public function testCreateUserNoBackends() {
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$this->assertFalse($manager->createUser('foo', 'bar'));
}
@ -431,7 +435,7 @@ class ManagerTest extends TestCase {
->with('MyUid', 'MyPassword')
->willReturn(false);
$manager = new Manager($config);
$manager = new Manager($config, $this->dispatcher);
$manager->createUserFromBackend('MyUid', 'MyPassword', $backend);
}
@ -471,7 +475,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend1);
$manager->registerBackend($backend2);
@ -479,7 +483,7 @@ class ManagerTest extends TestCase {
}
public function testCountUsersNoBackend() {
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$result = $manager->countUsers();
$this->assertTrue(is_array($result));
@ -504,7 +508,7 @@ class ManagerTest extends TestCase {
->method('getBackendName')
->will($this->returnValue('Mock_Test_Util_User_Dummy'));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend);
$result = $manager->countUsers();
@ -545,7 +549,7 @@ class ManagerTest extends TestCase {
->method('getBackendName')
->will($this->returnValue('Mock_Test_Util_User_Dummy'));
$manager = new \OC\User\Manager($this->config);
$manager = new \OC\User\Manager($this->config, $this->dispatcher);
$manager->registerBackend($backend1);
$manager->registerBackend($backend2);
@ -660,7 +664,7 @@ class ManagerTest extends TestCase {
->with('foo', 'login', 'lastLogin')
->will($this->returnValue(0));
$manager = new \OC\User\Manager($config);
$manager = new \OC\User\Manager($config, $this->dispatcher);
$backend = new \Test\Util\User\Dummy();
$manager->registerBackend($backend);
@ -694,7 +698,7 @@ class ManagerTest extends TestCase {
->with($this->equalTo('uid2'))
->will($this->returnValue(true));
$manager = new \OC\User\Manager($config);
$manager = new \OC\User\Manager($config, $this->dispatcher);
$manager->registerBackend($backend);
$users = $manager->getByEmail('test@example.com');

View File

@ -28,6 +28,7 @@ use OCP\IUser;
use OCP\Lockdown\ILockdownManager;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* @group DB
@ -167,7 +168,7 @@ class SessionTest extends \Test\TestCase {
'getUser'
])
->getMock();
$user = new User('sepp', null);
$user = new User('sepp', null, $this->createMock(EventDispatcherInterface::class));
$userSession->expects($this->once())
->method('getUser')
->will($this->returnValue($isLoggedIn ? $user : null));
@ -184,7 +185,7 @@ class SessionTest extends \Test\TestCase {
$backend = $this->createMock(\Test\Util\User\Dummy::class);
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
$user = $this->createMock(IUser::class);
$user->expects($this->once())
->method('getUID')
->will($this->returnValue('foo'));
@ -220,12 +221,12 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$backend = $this->createMock(\Test\Util\User\Dummy::class);
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('isEnabled')
->will($this->returnValue(true));
@ -271,12 +272,12 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$backend = $this->createMock(\Test\Util\User\Dummy::class);
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('isEnabled')
->will($this->returnValue(false));
@ -299,12 +300,12 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$backend = $this->createMock(\Test\Util\User\Dummy::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger);
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
$user = $this->createMock(IUser::class);
$session->expects($this->never())
->method('set');
@ -535,7 +536,7 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
@ -621,7 +622,7 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
@ -681,7 +682,7 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
@ -729,7 +730,7 @@ class SessionTest extends \Test\TestCase {
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->setConstructorArgs([$this->config, $this->createMock(EventDispatcherInterface::class)])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
@ -765,8 +766,8 @@ class SessionTest extends \Test\TestCase {
public function testActiveUserAfterSetSession() {
$users = array(
'foo' => new User('foo', null),
'bar' => new User('bar', null)
'foo' => new User('foo', null, $this->createMock(EventDispatcherInterface::class)),
'bar' => new User('bar', null, $this->createMock(EventDispatcherInterface::class))
);
$manager = $this->getMockBuilder('\OC\User\Manager')

View File

@ -17,6 +17,8 @@ use OCP\IUser;
use OCP\Notification\IManager as INotificationManager;
use OCP\Notification\INotification;
use OCP\UserInterface;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
/**
@ -27,6 +29,15 @@ use Test\TestCase;
* @package Test\User
*/
class UserTest extends TestCase {
/** @var EventDispatcherInterface|MockObject */
protected $dispatcher;
public function setUp() {
parent::setUp();
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
}
public function testDisplayName() {
/**
* @var \OC\User\Backend | \PHPUnit_Framework_MockObject_MockObject $backend
@ -42,7 +53,7 @@ class UserTest extends TestCase {
->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
->will($this->returnValue(true));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertEquals('Foo', $user->getDisplayName());
}
@ -64,7 +75,7 @@ class UserTest extends TestCase {
->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
->will($this->returnValue(true));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertEquals('foo', $user->getDisplayName());
}
@ -81,7 +92,7 @@ class UserTest extends TestCase {
->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
->will($this->returnValue(false));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertEquals('foo', $user->getDisplayName());
}
@ -104,7 +115,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->setPassword('bar',''));
}
@ -120,7 +131,7 @@ class UserTest extends TestCase {
->method('implementsActions')
->will($this->returnValue(false));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->setPassword('bar',''));
}
@ -144,7 +155,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->canChangeAvatar());
}
@ -168,7 +179,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->canChangeAvatar());
}
@ -184,7 +195,7 @@ class UserTest extends TestCase {
->method('implementsActions')
->willReturn(false);
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->canChangeAvatar());
}
@ -197,7 +208,7 @@ class UserTest extends TestCase {
->method('deleteUser')
->with($this->equalTo('foo'));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->delete());
}
@ -229,7 +240,7 @@ class UserTest extends TestCase {
->method('deleteUser')
->with($this->equalTo('foo'));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->delete());
}
@ -253,14 +264,14 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertEquals('/home/foo', $user->getHome());
}
public function testGetBackendClassName() {
$user = new User('foo', new \Test\Util\User\Dummy());
$user = new User('foo', new \Test\Util\User\Dummy(), $this->dispatcher);
$this->assertEquals('Dummy', $user->getBackendClassName());
$user = new User('foo', new \OC\User\Database());
$user = new User('foo', new \OC\User\Database(), $this->dispatcher);
$this->assertEquals('Database', $user->getBackendClassName());
}
@ -287,7 +298,7 @@ class UserTest extends TestCase {
->with($this->equalTo('datadirectory'))
->will($this->returnValue('arbitrary/path'));
$user = new User('foo', $backend, null, $allConfig);
$user = new User('foo', $backend, $this->dispatcher, null, $allConfig);
$this->assertEquals('arbitrary/path/foo', $user->getHome());
}
@ -307,7 +318,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->canChangePassword());
}
@ -321,7 +332,7 @@ class UserTest extends TestCase {
->method('implementsActions')
->will($this->returnValue(false));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->canChangePassword());
}
@ -341,7 +352,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->canChangeDisplayName());
}
@ -355,7 +366,7 @@ class UserTest extends TestCase {
->method('implementsActions')
->will($this->returnValue(false));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->canChangeDisplayName());
}
@ -380,7 +391,7 @@ class UserTest extends TestCase {
->with('foo','Foo')
->willReturn(true);
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertTrue($user->setDisplayName('Foo'));
$this->assertEquals('Foo',$user->getDisplayName());
}
@ -404,7 +415,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->setDisplayName(' '));
$this->assertEquals('foo',$user->getDisplayName());
}
@ -422,7 +433,7 @@ class UserTest extends TestCase {
$backend->expects($this->never())
->method('setDisplayName');
$user = new User('foo', $backend);
$user = new User('foo', $backend, $this->dispatcher);
$this->assertFalse($user->setDisplayName('Foo'));
$this->assertEquals('foo',$user->getDisplayName());
}
@ -462,7 +473,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend, $emitter);
$user = new User('foo', $backend, $this->dispatcher, $emitter);
$user->setPassword('bar','');
$this->assertEquals(2, $hooksCalled);
@ -492,7 +503,7 @@ class UserTest extends TestCase {
->method('deleteUser')
->willReturn($result);
$emitter = new PublicEmitter();
$user = new User('foo', $backend, $emitter);
$user = new User('foo', $backend, $this->dispatcher, $emitter);
/**
* @param User $user
@ -573,7 +584,7 @@ class UserTest extends TestCase {
->method('getAbsoluteURL')
->withAnyParameters()
->willReturn('http://localhost:8888/owncloud');
$user = new User('foo', $backend, null, null, $urlGenerator);
$user = new User('foo', $backend, $this->dispatcher, null, null, $urlGenerator);
$this->assertEquals('foo@localhost:8888/owncloud', $user->getCloudId());
}
@ -609,7 +620,7 @@ class UserTest extends TestCase {
'email'
);
$user = new User('foo', $backend, $emitter, $config);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$user->setEMailAddress('');
}
@ -646,7 +657,7 @@ class UserTest extends TestCase {
'foo@bar.com'
);
$user = new User('foo', $backend, $emitter, $config);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$user->setEMailAddress('foo@bar.com');
}
@ -674,7 +685,7 @@ class UserTest extends TestCase {
'foo@bar.com'
);
$user = new User('foo', $backend, $emitter, $config);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$user->setEMailAddress('foo@bar.com');
}
@ -711,7 +722,7 @@ class UserTest extends TestCase {
'23 TB'
);
$user = new User('foo', $backend, $emitter, $config);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$user->setQuota('23 TB');
}
@ -739,7 +750,7 @@ class UserTest extends TestCase {
'23 TB'
);
$user = new User('foo', $backend, $emitter, $config);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$user->setQuota('23 TB');
}
@ -759,7 +770,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend, null, $config);
$user = new User('foo', $backend, $this->dispatcher, null, $config);
$this->assertSame(42, $user->getLastLogin());
}
@ -779,7 +790,7 @@ class UserTest extends TestCase {
'true'
);
$user = new User('foo', $backend, null, $config);
$user = new User('foo', $backend, $this->dispatcher, null, $config);
$user->setEnabled(true);
}
@ -803,6 +814,7 @@ class UserTest extends TestCase {
->setConstructorArgs([
'foo',
$backend,
$this->dispatcher,
null,
$config,
])
@ -836,6 +848,7 @@ class UserTest extends TestCase {
->setConstructorArgs([
'foo',
$backend,
$this->dispatcher,
null,
$config,
])
@ -867,7 +880,7 @@ class UserTest extends TestCase {
}
}));
$user = new User('foo', $backend, null, $config);
$user = new User('foo', $backend, $this->dispatcher, null, $config);
$this->assertSame('foo@bar.com', $user->getEMailAddress());
}
}