379 lines
12 KiB
PHP
379 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @copyright Copyright (c) 2016 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/>.
|
|
*
|
|
*/
|
|
|
|
namespace OCA\Deck\Service;
|
|
|
|
use OCA\Deck\Db\Acl;
|
|
use OCA\Deck\Db\AclMapper;
|
|
use OCA\Deck\Db\Board;
|
|
use OCA\Deck\Db\BoardMapper;
|
|
use OCA\Deck\Db\IPermissionMapper;
|
|
use OCA\Deck\Db\User;
|
|
use OCA\Deck\NoPermissionException;
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
|
use OCP\IConfig;
|
|
use OCP\IGroup;
|
|
use OCP\IGroupManager;
|
|
use OCP\IRequest;
|
|
use OCP\IUser;
|
|
use OCP\IUserManager;
|
|
use OCP\Share\IManager;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class PermissionServiceTest extends \Test\TestCase {
|
|
private IRequest|MockObject $request;
|
|
private CirclesService|MockObject $circlesService;
|
|
private PermissionService $service;
|
|
private LoggerInterface|MockObject $logger;
|
|
private AclMapper|MockObject $aclMapper;
|
|
private BoardMapper|MockObject $boardMapper;
|
|
private IUserManager $userManager;
|
|
private IGroupManager|MockObject $groupManager;
|
|
private MockObject|IManager $shareManager;
|
|
private IConfig|MockObject $config;
|
|
|
|
public function setUp(): void {
|
|
parent::setUp();
|
|
$this->logger = $this->createMock(LoggerInterface::class);
|
|
$this->request = $this->createMock(IRequest::class);
|
|
$this->circlesService = $this->createMock(CirclesService::class);
|
|
$this->aclMapper = $this->createMock(AclMapper::class);
|
|
$this->boardMapper = $this->createMock(BoardMapper::class);
|
|
$this->userManager = $this->createMock(IUserManager::class);
|
|
$this->groupManager = $this->createMock(IGroupManager::class);
|
|
$this->shareManager = $this->createMock(IManager::class);
|
|
$this->config = $this->createMock(IConfig::class);
|
|
|
|
$this->service = new PermissionService(
|
|
$this->logger,
|
|
$this->circlesService,
|
|
$this->aclMapper,
|
|
$this->boardMapper,
|
|
$this->userManager,
|
|
$this->groupManager,
|
|
$this->shareManager,
|
|
$this->config,
|
|
'admin'
|
|
);
|
|
}
|
|
|
|
public function testGetPermissionsOwner() {
|
|
$board = new Board();
|
|
$board->setOwner('admin');
|
|
$this->boardMapper->expects($this->once())->method('find')->with(123)->willReturn($board);
|
|
$this->aclMapper->expects($this->once())
|
|
->method('findAll')
|
|
->willReturn(null);
|
|
$expected = [
|
|
Acl::PERMISSION_READ => true,
|
|
Acl::PERMISSION_EDIT => true,
|
|
Acl::PERMISSION_MANAGE => true,
|
|
Acl::PERMISSION_SHARE => true,
|
|
];
|
|
$this->assertEquals($expected, $this->service->getPermissions(123));
|
|
}
|
|
public function testGetPermissionsAcl() {
|
|
$board = new Board();
|
|
$board->setOwner('admin');
|
|
$this->boardMapper->expects($this->once())->method('find')->with(123)->willReturn($board);
|
|
$aclUser = new Acl();
|
|
$aclUser->setType('user');
|
|
$aclUser->setParticipant('admin');
|
|
$aclUser->setPermissionEdit(true);
|
|
$aclUser->setPermissionShare(true);
|
|
$aclUser->setPermissionManage(true);
|
|
$this->aclMapper->expects($this->once())
|
|
->method('findAll')
|
|
->willReturn([$aclUser]);
|
|
$expected = [
|
|
Acl::PERMISSION_READ => true,
|
|
Acl::PERMISSION_EDIT => true,
|
|
Acl::PERMISSION_MANAGE => true,
|
|
Acl::PERMISSION_SHARE => true,
|
|
];
|
|
$this->assertEquals($expected, $this->service->getPermissions(123));
|
|
}
|
|
public function testGetPermissionsAclNo() {
|
|
$board = new Board();
|
|
$board->setOwner('user1');
|
|
$this->boardMapper->expects($this->once())->method('find')->with(123)->willReturn($board);
|
|
$this->aclMapper->expects($this->once())
|
|
->method('findAll')
|
|
->willReturn([]);
|
|
$expected = [
|
|
Acl::PERMISSION_READ => false,
|
|
Acl::PERMISSION_EDIT => false,
|
|
Acl::PERMISSION_MANAGE => false,
|
|
Acl::PERMISSION_SHARE => false,
|
|
];
|
|
$this->assertEquals($expected, $this->service->getPermissions(123));
|
|
}
|
|
|
|
public function testUserIsBoardOwner() {
|
|
$adminBoard = new Board();
|
|
$adminBoard->setOwner('admin');
|
|
$userBoard = new Board();
|
|
$userBoard->setOwner('user1');
|
|
|
|
$this->boardMapper->expects($this->exactly(2))
|
|
->method('find')
|
|
->withConsecutive([123], [234])
|
|
->willReturnOnConsecutiveCalls($adminBoard, $userBoard);
|
|
|
|
$this->assertEquals(true, $this->service->userIsBoardOwner(123));
|
|
$this->assertEquals(false, $this->service->userIsBoardOwner(234));
|
|
}
|
|
|
|
public function testUserIsBoardOwnerNull() {
|
|
$this->boardMapper->expects($this->once())->method('find')->willThrowException(new DoesNotExistException('board does not exist'));
|
|
$this->assertEquals(false, $this->service->userIsBoardOwner(123));
|
|
}
|
|
|
|
public static function dataTestUserCan() {
|
|
return [
|
|
// participant permissions type
|
|
['admin', false, false, false, 'user', true, false, false, false],
|
|
['admin', true, false, false, 'user', true, true, false, false],
|
|
['admin', true, true, false, 'user', true, true, true, false],
|
|
['admin', true, true, false, 'user', true, true, true, false],
|
|
['admin', true, true, true, 'user', true, true, true, true],
|
|
['user1', false, false, false, 'user', false, false, false, false]
|
|
];
|
|
}
|
|
/** @dataProvider dataTestUserCan */
|
|
public function testUserCan($participant, $edit, $share, $manage, $type, $canRead, $canEdit, $canShare, $canManage) {
|
|
$aclUser = new Acl();
|
|
$aclUser->setType($type);
|
|
$aclUser->setParticipant($participant);
|
|
$aclUser->setPermissionEdit($edit);
|
|
$aclUser->setPermissionShare($share);
|
|
$aclUser->setPermissionManage($manage);
|
|
$acls = [
|
|
$aclUser
|
|
];
|
|
$this->assertEquals($canRead, $this->service->userCan($acls, Acl::PERMISSION_READ));
|
|
$this->assertEquals($canEdit, $this->service->userCan($acls, Acl::PERMISSION_EDIT));
|
|
$this->assertEquals($canShare, $this->service->userCan($acls, Acl::PERMISSION_SHARE));
|
|
$this->assertEquals($canManage, $this->service->userCan($acls, Acl::PERMISSION_MANAGE));
|
|
}
|
|
|
|
public function testUserCanFail() {
|
|
$this->assertFalse($this->service->userCan([], Acl::PERMISSION_EDIT));
|
|
}
|
|
|
|
public static function dataCheckPermission() {
|
|
return [
|
|
// see getAcls() for set permissions
|
|
[1, Acl::PERMISSION_READ, true],
|
|
[1, Acl::PERMISSION_EDIT, false],
|
|
[1, Acl::PERMISSION_MANAGE, false],
|
|
[1, Acl::PERMISSION_SHARE, false],
|
|
|
|
[2, Acl::PERMISSION_READ, true],
|
|
[2, Acl::PERMISSION_EDIT, true],
|
|
[2, Acl::PERMISSION_MANAGE, false],
|
|
[2, Acl::PERMISSION_SHARE, false],
|
|
|
|
[3, Acl::PERMISSION_READ, true],
|
|
[3, Acl::PERMISSION_EDIT, false],
|
|
[3, Acl::PERMISSION_MANAGE, true],
|
|
[3, Acl::PERMISSION_SHARE, false],
|
|
|
|
[4, Acl::PERMISSION_READ, true],
|
|
[4, Acl::PERMISSION_EDIT, false],
|
|
[4, Acl::PERMISSION_MANAGE, false],
|
|
[4, Acl::PERMISSION_SHARE, true],
|
|
|
|
[null, Acl::PERMISSION_READ, false],
|
|
[6, Acl::PERMISSION_READ, false],
|
|
|
|
[1, Acl::PERMISSION_READ, true, 'admin'],
|
|
[1, Acl::PERMISSION_EDIT, true, 'admin'],
|
|
[1, Acl::PERMISSION_MANAGE, true, 'admin'],
|
|
[1, Acl::PERMISSION_SHARE, true, 'admin'],
|
|
];
|
|
}
|
|
|
|
/** @dataProvider dataCheckPermission */
|
|
public function testCheckPermission($boardId, $permission, $result, $owner = 'foo') {
|
|
// Setup mapper
|
|
$mapper = $this->getMockBuilder(IPermissionMapper::class)->getMock();
|
|
|
|
// board owner
|
|
$mapper->expects($this->once())->method('findBoardId')->willReturn($boardId);
|
|
$board = new Board();
|
|
$board->setId($boardId);
|
|
$board->setOwner($owner);
|
|
$board->setAcl($this->getAcls($boardId));
|
|
$this->boardMapper->expects($this->any())->method('find')->willReturn($board);
|
|
|
|
$this->aclMapper->expects($this->any())
|
|
->method('findAll')
|
|
->with($boardId)
|
|
->willReturn($this->getAcls($boardId));
|
|
|
|
$this->shareManager->expects($this->any())
|
|
->method('sharingDisabledForUser')
|
|
->willReturn(false);
|
|
|
|
if ($result) {
|
|
$actual = $this->service->checkPermission($mapper, 1234, $permission);
|
|
$this->assertTrue($actual);
|
|
} else {
|
|
$this->expectException(NoPermissionException::class);
|
|
$this->service->checkPermission($mapper, 1234, $permission);
|
|
}
|
|
}
|
|
|
|
/** @dataProvider dataCheckPermission */
|
|
public function testCheckPermissionWithoutMapper($boardId, $permission, $result, $owner = 'foo') {
|
|
$mapper = null;
|
|
$board = new Board();
|
|
$board->setId($boardId);
|
|
$board->setOwner($owner);
|
|
$board->setAcl($this->getAcls($boardId));
|
|
if ($boardId === null) {
|
|
$this->boardMapper->expects($this->any())->method('find')->willThrowException(new DoesNotExistException('not found'));
|
|
} else {
|
|
$this->boardMapper->expects($this->any())->method('find')->willReturn($board);
|
|
}
|
|
|
|
$this->aclMapper->expects($this->any())
|
|
->method('findAll')
|
|
->with($boardId)
|
|
->willReturn($this->getAcls($boardId));
|
|
|
|
if ($result) {
|
|
$actual = $this->service->checkPermission($mapper, $boardId, $permission);
|
|
$this->assertTrue($actual);
|
|
} else {
|
|
$this->expectException(NoPermissionException::class);
|
|
$this->service->checkPermission($mapper, $boardId, $permission);
|
|
}
|
|
}
|
|
|
|
public function testCheckPermissionNotFound() {
|
|
$mapper = $this->getMockBuilder(IPermissionMapper::class)->getMock();
|
|
$mapper->expects($this->once())->method('findBoardId')->willThrowException(new NoPermissionException(null));
|
|
$this->expectException(NoPermissionException::class);
|
|
$this->service->checkPermission($mapper, 1234, Acl::PERMISSION_READ);
|
|
}
|
|
|
|
private function generateAcl($boardId, $type, $participant, $edit, $manage, $share) {
|
|
$acl = new Acl();
|
|
$acl->setParticipant($participant);
|
|
$acl->setBoardId($boardId);
|
|
$acl->setType($type);
|
|
$acl->setPermissionEdit($edit);
|
|
$acl->setPermissionShare($share);
|
|
$acl->setPermissionManage($manage);
|
|
return $acl;
|
|
}
|
|
|
|
private function getAcls($boardId) {
|
|
$acls = [
|
|
$this->generateAcl(1, 'user', 'admin', false, false, false),
|
|
$this->generateAcl(2, 'user', 'admin', true, false, false),
|
|
$this->generateAcl(3, 'user', 'admin', false, true, false),
|
|
$this->generateAcl(4, 'user', 'admin', false, false, true),
|
|
$this->generateAcl(5, 'group', 'admin', false, false, false),
|
|
$this->generateAcl(6, 'user', 'foo', false, false, false)
|
|
];
|
|
$result = [];
|
|
foreach ($acls as $acl) {
|
|
if ($acl->getBoardId() === $boardId) {
|
|
$result[] = $acl;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public function testFindUsersFail() {
|
|
$this->boardMapper->expects($this->once())
|
|
->method('find')
|
|
->with(123)
|
|
->will($this->throwException(new DoesNotExistException('')));
|
|
$users = $this->service->findUsers(123);
|
|
$this->assertEquals([], $users);
|
|
}
|
|
|
|
/**
|
|
* @param $uid
|
|
* @return IUser
|
|
*/
|
|
private function mockUser($uid) {
|
|
$user = $this->createMock(IUser::class);
|
|
$user->expects($this->any())
|
|
->method('getUID')
|
|
->willReturn($uid);
|
|
return $user;
|
|
}
|
|
|
|
public function testFindUsers() {
|
|
$user1 = $this->mockUser('user1');
|
|
$user2 = $this->mockUser('user2');
|
|
$user3 = $this->mockUser('user3');
|
|
$aclUser = new Acl();
|
|
$aclUser->setType(Acl::PERMISSION_TYPE_USER);
|
|
$aclUser->setParticipant('user2');
|
|
$aclGroup = new Acl();
|
|
$aclGroup->setType(Acl::PERMISSION_TYPE_GROUP);
|
|
$aclGroup->setParticipant('group1');
|
|
|
|
$board = $this->createMock(Board::class);
|
|
$board->expects($this->any())
|
|
->method('__call')
|
|
->with('getOwner', [])
|
|
->willReturn('user1');
|
|
$this->aclMapper->expects($this->once())
|
|
->method('findAll')
|
|
->with(123)
|
|
->willReturn([$aclUser, $aclGroup]);
|
|
$this->boardMapper->expects($this->once())
|
|
->method('find')
|
|
->with(123)
|
|
->willReturn($board);
|
|
$this->userManager->expects($this->any())
|
|
->method('userExists')
|
|
->withConsecutive(['user1'], ['user2'])
|
|
->willReturnOnConsecutiveCalls($user1, $user2);
|
|
|
|
$group = $this->createMock(IGroup::class);
|
|
$group->expects($this->once())
|
|
->method('getUsers')
|
|
->willReturn([$user3]);
|
|
$this->groupManager->expects($this->once())
|
|
->method('get')
|
|
->with('group1')
|
|
->willReturn($group);
|
|
$users = $this->service->findUsers(123);
|
|
$this->assertEquals([
|
|
'user1' => new User($user1->getUID(), $this->userManager),
|
|
'user2' => new User($user2->getUID(), $this->userManager),
|
|
'user3' => new User($user3->getUID(), $this->userManager),
|
|
], $users);
|
|
}
|
|
}
|