From c6b25a6438b8facbb9acc931137ad98b46649c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 4 Apr 2020 12:13:21 +0200 Subject: [PATCH] Let new shares only use the current users permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/Service/BoardService.php | 15 +++++ tests/unit/Service/BoardServiceTest.php | 88 +++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 838e4f6d8..443a232da 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -454,6 +454,17 @@ class BoardService { return $board; } + private function applyPermissions($boardId, $edit, $share, $manage) { + try { + $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE); + } catch (NoPermissionException $e) { + $acls = $this->aclMapper->findAll($boardId); + $edit = $this->permissionService->userCan($acls, Acl::PERMISSION_EDIT, $this->userId) && $edit; + $share = $this->permissionService->userCan($acls, Acl::PERMISSION_SHARE, $this->userId) && $share; + $manage = $this->permissionService->userCan($acls, Acl::PERMISSION_MANAGE, $this->userId) && $manage; + } + return [$edit, $share, $manage]; + } /** * @param $boardId @@ -493,6 +504,8 @@ class BoardService { } $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_SHARE); + [$edit, $share, $manage] = $this->applyPermissions($boardId, $edit, $share, $manage); + $acl = new Acl(); $acl->setBoardId($boardId); $acl->setType($type); @@ -555,8 +568,10 @@ class BoardService { } $this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE); + /** @var Acl $acl */ $acl = $this->aclMapper->find($id); + [$edit, $share, $manage] = $this->applyPermissions($acl->getBoardId(), $edit, $share, $manage); $acl->setPermissionEdit($edit); $acl->setPermissionShare($share); $acl->setPermissionManage($manage); diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index 3616359db..2bc874c54 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -34,6 +34,7 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\ChangeHelper; use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\StackMapper; +use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; use OCP\IUser; use OCP\IUserManager; @@ -260,6 +261,93 @@ class BoardServiceTest extends TestCase { )); } + public function dataAddAclExtendPermission() { + return [ + [[false, false, false], [false, false, false], [false, false, false]], + [[false, false, false], [true, true, true], [false, false, false]], + + // user has share permissions -> can only reshare with those + [[false, true, false], [false, false, false], [false, false, false]], + [[false, true, false], [false, true, false], [false, true, false]], + [[false, true, false], [true, true, true], [false, true, false]], + + // user has write permissions -> can only reshare with those + [[true, true, false], [false, false, false], [false, false, false]], + [[true, true, false], [false, true, false], [false, true, false]], + [[true, true, false], [true, true, true], [true, true, false]], + + // user has manage permissions -> can upgrade acl permissions + [[false, false, true], [true, true, true], [true, true, true]], + [[true, true, true], [false, false, true], [false, false, true]], + ]; + } + + /** + * @dataProvider dataAddAclExtendPermission + * @param $currentUserAcl + * @param $providedAcl + * @param $resultingAcl + * @throws NoPermissionException + * @throws \OCA\Deck\BadRequestException + */ + public function testAddAclExtendPermission($currentUserAcl, $providedAcl, $resultingAcl) { + $existingAcl = new Acl(); + $existingAcl->setBoardId(123); + $existingAcl->setType('user'); + $existingAcl->setParticipant('admin'); + $existingAcl->setPermissionEdit($currentUserAcl[0]); + $existingAcl->setPermissionShare($currentUserAcl[1]); + $existingAcl->setPermissionManage($currentUserAcl[2]); + $this->permissionService->expects($this->at(0)) + ->method('checkPermission') + ->with($this->boardMapper, 123, Acl::PERMISSION_SHARE, null); + if ($currentUserAcl[2]) { + $this->permissionService->expects($this->at(1)) + ->method('checkPermission') + ->with($this->boardMapper, 123, Acl::PERMISSION_MANAGE, null); + } else { + $this->aclMapper->expects($this->once()) + ->method('findAll') + ->willReturn([$existingAcl]); + $this->permissionService->expects($this->at(1)) + ->method('checkPermission') + ->with($this->boardMapper, 123, Acl::PERMISSION_MANAGE, null) + ->willThrowException(new NoPermissionException('No permission')); + $this->permissionService->expects($this->at(2)) + ->method('userCan') + ->willReturn($currentUserAcl[0]); + $this->permissionService->expects($this->at(3)) + ->method('userCan') + ->willReturn($currentUserAcl[1]); + $this->permissionService->expects($this->at(4)) + ->method('userCan') + ->willReturn($currentUserAcl[2]); + } + + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('admin'); + $acl = new Acl(); + $acl->setBoardId(123); + $acl->setType('user'); + $acl->setParticipant('admin'); + $acl->setPermissionEdit($resultingAcl[0]); + $acl->setPermissionShare($resultingAcl[1]); + $acl->setPermissionManage($resultingAcl[2]); + $acl->resolveRelation('participant', function($participant) use (&$user) { + return null; + }); + $this->notificationHelper->expects($this->once()) + ->method('sendBoardShared'); + $expected = clone $acl; + $this->aclMapper->expects($this->once()) + ->method('insert') + ->with($acl) + ->willReturn($acl); + $this->assertEquals($expected, $this->service->addAcl( + 123, 'user', 'admin', $providedAcl[0], $providedAcl[1], $providedAcl[2] + )); + } + public function testUpdateAcl() { $acl = new Acl(); $acl->setBoardId(123);