diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagMappingNode.php | 83 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagNode.php | 43 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagPlugin.php | 68 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsByIdCollection.php | 9 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php | 73 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsObjectTypeCollection.php | 13 | ||||
-rw-r--r-- | apps/dav/tests/unit/systemtag/systemtagmappingnode.php | 58 | ||||
-rw-r--r-- | apps/dav/tests/unit/systemtag/systemtagnode.php | 82 | ||||
-rw-r--r-- | apps/dav/tests/unit/systemtag/systemtagplugin.php | 350 | ||||
-rw-r--r-- | apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php | 57 | ||||
-rw-r--r-- | apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php | 165 | ||||
-rw-r--r-- | apps/systemtags/js/systemtagsinfoview.js | 2 | ||||
-rw-r--r-- | apps/systemtags/lib/Activity/Extension.php | 2 | ||||
-rw-r--r-- | apps/systemtags/tests/js/systemtagsinfoviewSpec.js | 43 |
14 files changed, 685 insertions, 363 deletions
diff --git a/apps/dav/lib/SystemTag/SystemTagMappingNode.php b/apps/dav/lib/SystemTag/SystemTagMappingNode.php index bb2936c13dc..09a3c79c757 100644 --- a/apps/dav/lib/SystemTag/SystemTagMappingNode.php +++ b/apps/dav/lib/SystemTag/SystemTagMappingNode.php @@ -24,21 +24,22 @@ namespace OCA\DAV\SystemTag; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\Exception\MethodNotAllowed; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; +use OCP\IUser; /** * Mapping node for system tag to object id */ -class SystemTagMappingNode extends SystemTagNode { - +class SystemTagMappingNode implements \Sabre\DAV\INode { /** - * @var ISystemTagObjectMapper + * @var ISystemTag */ - private $tagMapper; + protected $tag; /** * @var string @@ -51,12 +52,29 @@ class SystemTagMappingNode extends SystemTagNode { private $objectType; /** + * User + * + * @var IUser + */ + protected $user; + + /** + * @var ISystemTagManager + */ + protected $tagManager; + + /** + * @var ISystemTagObjectMapper + */ + private $tagMapper; + + /** * Sets up the node, expects a full path name * * @param ISystemTag $tag system tag * @param string $objectId * @param string $objectType - * @param bool $isAdmin whether to allow permissions for admin + * @param IUser $user user * @param ISystemTagManager $tagManager * @param ISystemTagObjectMapper $tagMapper */ @@ -64,14 +82,16 @@ class SystemTagMappingNode extends SystemTagNode { ISystemTag $tag, $objectId, $objectType, - $isAdmin, + IUser $user, ISystemTagManager $tagManager, ISystemTagObjectMapper $tagMapper ) { + $this->tag = $tag; $this->objectId = $objectId; $this->objectType = $objectType; + $this->user = $user; + $this->tagManager = $tagManager; $this->tagMapper = $tagMapper; - parent::__construct($tag, $isAdmin, $tagManager); } /** @@ -93,17 +113,52 @@ class SystemTagMappingNode extends SystemTagNode { } /** + * Returns the system tag represented by this node + * + * @return ISystemTag system tag + */ + public function getSystemTag() { + return $this->tag; + } + + /** + * Returns the id of the tag + * + * @return string + */ + public function getName() { + return $this->tag->getId(); + } + + /** + * Renames the node + * + * @param string $name The new name + * + * @throws MethodNotAllowed not allowed to rename node + */ + public function setName($name) { + throw new MethodNotAllowed(); + } + + /** + * Returns null, not supported + * + */ + public function getLastModified() { + return null; + } + + /** * Delete tag to object association */ public function delete() { try { - if (!$this->isAdmin) { - if (!$this->tag->isUserVisible()) { - throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found'); - } - if (!$this->tag->isUserAssignable()) { - throw new Forbidden('No permission to unassign tag ' . $this->tag->getId()); - } + if (!$this->tagManager->canUserSeeTag($this->tag, $this->user)) { + throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found'); + } + if (!$this->tagManager->canUserAssignTag($this->tag, $this->user)) { + throw new Forbidden('No permission to unassign tag ' . $this->tag->getId()); } $this->tagMapper->unassignTags($this->objectId, $this->objectType, $this->tag->getId()); } catch (TagNotFoundException $e) { diff --git a/apps/dav/lib/SystemTag/SystemTagNode.php b/apps/dav/lib/SystemTag/SystemTagNode.php index 500e1a3adea..f139a3335c8 100644 --- a/apps/dav/lib/SystemTag/SystemTagNode.php +++ b/apps/dav/lib/SystemTag/SystemTagNode.php @@ -32,6 +32,7 @@ use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\TagNotFoundException; use OCP\SystemTag\TagAlreadyExistsException; +use OCP\IUser; /** * DAV node representing a system tag, with the name being the tag id. @@ -49,6 +50,13 @@ class SystemTagNode implements \Sabre\DAV\INode { protected $tagManager; /** + * User + * + * @var IUser + */ + protected $user; + + /** * Whether to allow permissions for admins * * @var bool @@ -59,11 +67,13 @@ class SystemTagNode implements \Sabre\DAV\INode { * Sets up the node, expects a full path name * * @param ISystemTag $tag system tag + * @param IUser $user user * @param bool $isAdmin whether to allow operations for admins - * @param ISystemTagManager $tagManager + * @param ISystemTagManager $tagManager tag manager */ - public function __construct(ISystemTag $tag, $isAdmin, ISystemTagManager $tagManager) { + public function __construct(ISystemTag $tag, IUser $user, $isAdmin, ISystemTagManager $tagManager) { $this->tag = $tag; + $this->user = $user; $this->isAdmin = $isAdmin; $this->tagManager = $tagManager; } @@ -109,14 +119,15 @@ class SystemTagNode implements \Sabre\DAV\INode { */ public function update($name, $userVisible, $userAssignable) { try { - if (!$this->isAdmin) { - if (!$this->tag->isUserVisible()) { - throw new NotFound('Tag with id ' . $this->tag->getId() . ' does not exist'); - } - if (!$this->tag->isUserAssignable()) { - throw new Forbidden('No permission to update tag ' . $this->tag->getId()); - } + if (!$this->tagManager->canUserSeeTag($this->tag, $this->user)) { + throw new NotFound('Tag with id ' . $this->tag->getId() . ' does not exist'); + } + if (!$this->tagManager->canUserAssignTag($this->tag, $this->user)) { + throw new Forbidden('No permission to update tag ' . $this->tag->getId()); + } + // only admin is able to change permissions, regular users can only rename + if (!$this->isAdmin) { // only renaming is allowed for regular users if ($userVisible !== $this->tag->isUserVisible() || $userAssignable !== $this->tag->isUserAssignable() @@ -124,6 +135,7 @@ class SystemTagNode implements \Sabre\DAV\INode { throw new Forbidden('No permission to update permissions for tag ' . $this->tag->getId()); } } + $this->tagManager->updateTag($this->tag->getId(), $name, $userVisible, $userAssignable); } catch (TagNotFoundException $e) { throw new NotFound('Tag with id ' . $this->tag->getId() . ' does not exist'); @@ -145,14 +157,13 @@ class SystemTagNode implements \Sabre\DAV\INode { public function delete() { try { - if (!$this->isAdmin) { - if (!$this->tag->isUserVisible()) { - throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found'); - } - if (!$this->tag->isUserAssignable()) { - throw new Forbidden('No permission to delete tag ' . $this->tag->getId()); - } + if (!$this->tagManager->canUserSeeTag($this->tag, $this->user)) { + throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found'); } + if (!$this->tagManager->canUserAssignTag($this->tag, $this->user)) { + throw new Forbidden('No permission to delete tag ' . $this->tag->getId()); + } + $this->tagManager->deleteTags($this->tag->getId()); } catch (TagNotFoundException $e) { // can happen if concurrent deletion occurred diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php index a266b4a1214..af683954b87 100644 --- a/apps/dav/lib/SystemTag/SystemTagPlugin.php +++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php @@ -24,18 +24,20 @@ namespace OCA\DAV\SystemTag; use OCP\IGroupManager; use OCP\IUserSession; -use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropFind; use Sabre\DAV\PropPatch; use Sabre\DAV\Exception\BadRequest; -use Sabre\DAV\Exception\UnsupportedMediaType; use Sabre\DAV\Exception\Conflict; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\Exception\NotFound; +use Sabre\DAV\Exception\UnsupportedMediaType; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\TagAlreadyExistsException; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; +use OCA\DAV\SystemTag\SystemTagMappingNode; /** * Sabre plugin to handle system tags: @@ -52,6 +54,8 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { const DISPLAYNAME_PROPERTYNAME = '{http://owncloud.org/ns}display-name'; const USERVISIBLE_PROPERTYNAME = '{http://owncloud.org/ns}user-visible'; const USERASSIGNABLE_PROPERTYNAME = '{http://owncloud.org/ns}user-assignable'; + const GROUPS_PROPERTYNAME = '{http://owncloud.org/ns}groups'; + const CANASSIGN_PROPERTYNAME = '{http://owncloud.org/ns}can-assign'; /** * @var \Sabre\DAV\Server $server @@ -181,14 +185,26 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { $userAssignable = (bool)$data['userAssignable']; } - if($userVisible === false || $userAssignable === false) { + $groups = []; + if (isset($data['groups'])) { + $groups = $data['groups']; + if (is_string($groups)) { + $groups = explode('|', $groups); + } + } + + if($userVisible === false || $userAssignable === false || !empty($groups)) { if(!$this->userSession->isLoggedIn() || !$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { throw new BadRequest('Not sufficient permissions'); } } try { - return $this->tagManager->createTag($tagName, $userVisible, $userAssignable); + $tag = $this->tagManager->createTag($tagName, $userVisible, $userAssignable); + if (!empty($groups)) { + $this->tagManager->setTagGroups($tag, $groups); + } + return $tag; } catch (TagAlreadyExistsException $e) { throw new Conflict('Tag already exists', 0, $e); } @@ -205,7 +221,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { PropFind $propFind, \Sabre\DAV\INode $node ) { - if (!($node instanceof SystemTagNode)) { + if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagMappingNode)) { return; } @@ -222,8 +238,27 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { }); $propFind->handle(self::USERASSIGNABLE_PROPERTYNAME, function() use ($node) { + // this is the tag's inherent property "is user assignable" return $node->getSystemTag()->isUserAssignable() ? 'true' : 'false'; }); + + $propFind->handle(self::CANASSIGN_PROPERTYNAME, function() use ($node) { + // this is the effective permission for the current user + return $this->tagManager->canUserAssignTag($node->getSystemTag(), $this->userSession->getUser()) ? 'true' : 'false'; + }); + + $propFind->handle(self::GROUPS_PROPERTYNAME, function() use ($node) { + if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { + // property only available for admins + throw new Forbidden(); + } + $groups = []; + // no need to retrieve groups for namespaces that don't qualify + if ($node->getSystemTag()->isUserVisible() && !$node->getSystemTag()->isUserAssignable()) { + $groups = $this->tagManager->getTagGroups($node->getSystemTag()); + } + return implode('|', $groups); + }); } /** @@ -239,6 +274,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { self::DISPLAYNAME_PROPERTYNAME, self::USERVISIBLE_PROPERTYNAME, self::USERASSIGNABLE_PROPERTYNAME, + self::GROUPS_PROPERTYNAME, ], function($props) use ($path) { $node = $this->server->tree->getNodeForPath($path); if (!($node instanceof SystemTagNode)) { @@ -250,22 +286,42 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { $userVisible = $tag->isUserVisible(); $userAssignable = $tag->isUserAssignable(); + $updateTag = false; + if (isset($props[self::DISPLAYNAME_PROPERTYNAME])) { $name = $props[self::DISPLAYNAME_PROPERTYNAME]; + $updateTag = true; } if (isset($props[self::USERVISIBLE_PROPERTYNAME])) { $propValue = $props[self::USERVISIBLE_PROPERTYNAME]; $userVisible = ($propValue !== 'false' && $propValue !== '0'); + $updateTag = true; } if (isset($props[self::USERASSIGNABLE_PROPERTYNAME])) { $propValue = $props[self::USERASSIGNABLE_PROPERTYNAME]; $userAssignable = ($propValue !== 'false' && $propValue !== '0'); + $updateTag = true; + } + + if (isset($props[self::GROUPS_PROPERTYNAME])) { + if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { + // property only available for admins + throw new Forbidden(); + } + + $propValue = $props[self::GROUPS_PROPERTYNAME]; + $groupIds = explode('|', $propValue); + $this->tagManager->setTagGroups($tag, $groupIds); + } + + if ($updateTag) { + $node->update($name, $userVisible, $userAssignable); } - $node->update($name, $userVisible, $userAssignable); return true; }); + } } diff --git a/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php b/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php index 298902501ab..2b24bce9f35 100644 --- a/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php +++ b/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php @@ -32,6 +32,7 @@ use OCP\SystemTag\ISystemTag; use OCP\SystemTag\TagNotFoundException; use OCP\IGroupManager; use OCP\IUserSession; +use OC\User\NoUserException; class SystemTagsByIdCollection implements ICollection { @@ -69,6 +70,8 @@ class SystemTagsByIdCollection implements ICollection { /** * Returns whether the currently logged in user is an administrator + * + * @return bool true if the user is an admin */ private function isAdmin() { $user = $this->userSession->getUser(); @@ -101,7 +104,7 @@ class SystemTagsByIdCollection implements ICollection { try { $tag = $this->tagManager->getTagsByIds([$name]); $tag = current($tag); - if (!$this->isAdmin() && !$tag->isUserVisible()) { + if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { throw new NotFound('Tag with id ' . $name . ' not found'); } return $this->makeNode($tag); @@ -131,7 +134,7 @@ class SystemTagsByIdCollection implements ICollection { try { $tag = $this->tagManager->getTagsByIds([$name]); $tag = current($tag); - if (!$this->isAdmin() && !$tag->isUserVisible()) { + if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { return false; } return true; @@ -171,6 +174,6 @@ class SystemTagsByIdCollection implements ICollection { * @return SystemTagNode */ private function makeNode(ISystemTag $tag) { - return new SystemTagNode($tag, $this->isAdmin(), $this->tagManager); + return new SystemTagNode($tag, $this->userSession->getUser(), $this->isAdmin(), $this->tagManager); } } diff --git a/apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php b/apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php index eb75ed06393..c4c45dc76d6 100644 --- a/apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php +++ b/apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php @@ -31,6 +31,7 @@ use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\TagNotFoundException; +use OCP\IUser; /** * Collection containing tags by object id @@ -58,11 +59,11 @@ class SystemTagsObjectMappingCollection implements ICollection { private $tagMapper; /** - * Whether to return results only visible for admins + * User * - * @var bool + * @var IUser */ - private $isAdmin; + private $user; /** @@ -70,30 +71,35 @@ class SystemTagsObjectMappingCollection implements ICollection { * * @param string $objectId object id * @param string $objectType object type - * @param bool $isAdmin whether to return results visible only for admins - * @param ISystemTagManager $tagManager - * @param ISystemTagObjectMapper $tagMapper + * @param IUser $user user + * @param ISystemTagManager $tagManager tag manager + * @param ISystemTagObjectMapper $tagMapper tag mapper */ - public function __construct($objectId, $objectType, $isAdmin, $tagManager, $tagMapper) { + public function __construct( + $objectId, + $objectType, + IUser $user, + ISystemTagManager $tagManager, + ISystemTagObjectMapper $tagMapper + ) { $this->tagManager = $tagManager; $this->tagMapper = $tagMapper; $this->objectId = $objectId; $this->objectType = $objectType; - $this->isAdmin = $isAdmin; + $this->user = $user; } function createFile($tagId, $data = null) { try { - if (!$this->isAdmin) { - $tag = $this->tagManager->getTagsByIds($tagId); - $tag = current($tag); - if (!$tag->isUserVisible()) { - throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); - } - if (!$tag->isUserAssignable()) { - throw new Forbidden('No permission to assign tag ' . $tag->getId()); - } + $tags = $this->tagManager->getTagsByIds([$tagId]); + $tag = current($tags); + if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { + throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); } + if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { + throw new Forbidden('No permission to assign tag ' . $tagId); + } + $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); } catch (TagNotFoundException $e) { throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); @@ -109,7 +115,7 @@ class SystemTagsObjectMappingCollection implements ICollection { if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) { $tag = $this->tagManager->getTagsByIds([$tagId]); $tag = current($tag); - if ($this->isAdmin || $tag->isUserVisible()) { + if ($this->tagManager->canUserSeeTag($tag, $this->user)) { return $this->makeNode($tag); } } @@ -127,12 +133,12 @@ class SystemTagsObjectMappingCollection implements ICollection { return []; } $tags = $this->tagManager->getTagsByIds($tagIds); - if (!$this->isAdmin) { - // filter out non-visible tags - $tags = array_filter($tags, function($tag) { - return $tag->isUserVisible(); - }); - } + + // filter out non-visible tags + $tags = array_filter($tags, function($tag) { + return $this->tagManager->canUserSeeTag($tag, $this->user); + }); + return array_values(array_map(function($tag) { return $this->makeNode($tag); }, $tags)); @@ -141,17 +147,16 @@ class SystemTagsObjectMappingCollection implements ICollection { function childExists($tagId) { try { $result = ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)); - if ($this->isAdmin || !$result) { - return $result; - } - // verify if user is allowed to see this tag - $tag = $this->tagManager->getTagsByIds($tagId); - $tag = current($tag); - if (!$tag->isUserVisible()) { - return false; + if ($result) { + $tags = $this->tagManager->getTagsByIds([$tagId]); + $tag = current($tags); + if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { + return false; + } } - return true; + + return $result; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { @@ -193,7 +198,7 @@ class SystemTagsObjectMappingCollection implements ICollection { $tag, $this->objectId, $this->objectType, - $this->isAdmin, + $this->user, $this->tagManager, $this->tagMapper ); diff --git a/apps/dav/lib/SystemTag/SystemTagsObjectTypeCollection.php b/apps/dav/lib/SystemTag/SystemTagsObjectTypeCollection.php index bdbc73c4e32..ae4b9d51a1b 100644 --- a/apps/dav/lib/SystemTag/SystemTagsObjectTypeCollection.php +++ b/apps/dav/lib/SystemTag/SystemTagsObjectTypeCollection.php @@ -95,17 +95,6 @@ class SystemTagsObjectTypeCollection implements ICollection { } /** - * Returns whether the currently logged in user is an administrator - */ - private function isAdmin() { - $user = $this->userSession->getUser(); - if ($user !== null) { - return $this->groupManager->isAdmin($user->getUID()); - } - return false; - } - - /** * @param string $name * @param resource|string $data Initial payload * @throws Forbidden @@ -132,7 +121,7 @@ class SystemTagsObjectTypeCollection implements ICollection { return new SystemTagsObjectMappingCollection( $objectId, $this->objectType, - $this->isAdmin(), + $this->userSession->getUser(), $this->tagManager, $this->tagMapper ); diff --git a/apps/dav/tests/unit/systemtag/systemtagmappingnode.php b/apps/dav/tests/unit/systemtag/systemtagmappingnode.php index 7f2ff7d6616..f0e1c3bc567 100644 --- a/apps/dav/tests/unit/systemtag/systemtagmappingnode.php +++ b/apps/dav/tests/unit/systemtag/systemtagmappingnode.php @@ -24,6 +24,7 @@ namespace OCA\DAV\Tests\Unit\SystemTag; use Sabre\DAV\Exception\NotFound; use OC\SystemTag\SystemTag; use OCP\SystemTag\TagNotFoundException; +use OCP\SystemTag\ISystemTag; class SystemTagMappingNode extends \Test\TestCase { @@ -37,14 +38,20 @@ class SystemTagMappingNode extends \Test\TestCase { */ private $tagMapper; + /** + * @var \OCP\IUser + */ + private $user; + protected function setUp() { parent::setUp(); $this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager'); $this->tagMapper = $this->getMock('\OCP\SystemTag\ISystemTagObjectMapper'); + $this->user = $this->getMock('\OCP\IUser'); } - public function getMappingNode($isAdmin = true, $tag = null) { + public function getMappingNode($tag = null) { if ($tag === null) { $tag = new SystemTag(1, 'Test', true, true); } @@ -52,7 +59,7 @@ class SystemTagMappingNode extends \Test\TestCase { $tag, 123, 'files', - $isAdmin, + $this->user, $this->tagManager, $this->tagMapper ); @@ -60,28 +67,30 @@ class SystemTagMappingNode extends \Test\TestCase { public function testGetters() { $tag = new SystemTag(1, 'Test', true, false); - $node = $this->getMappingNode(true, $tag); + $node = $this->getMappingNode($tag); $this->assertEquals('1', $node->getName()); $this->assertEquals($tag, $node->getSystemTag()); $this->assertEquals(123, $node->getObjectId()); $this->assertEquals('files', $node->getObjectType()); } - public function adminFlagProvider() { - return [[true], [false]]; - } - - /** - * @dataProvider adminFlagProvider - */ - public function testDeleteTag($isAdmin) { + public function testDeleteTag() { + $node = $this->getMappingNode(); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($node->getSystemTag()) + ->will($this->returnValue(true)); + $this->tagManager->expects($this->once()) + ->method('canUserAssignTag') + ->with($node->getSystemTag()) + ->will($this->returnValue(true)); $this->tagManager->expects($this->never()) ->method('deleteTags'); $this->tagMapper->expects($this->once()) ->method('unassignTags') ->with(123, 'files', 1); - $this->getMappingNode($isAdmin)->delete(); + $node->delete(); } public function tagNodeDeleteProviderPermissionException() { @@ -102,7 +111,15 @@ class SystemTagMappingNode extends \Test\TestCase { /** * @dataProvider tagNodeDeleteProviderPermissionException */ - public function testDeleteTagExpectedException($tag, $expectedException) { + public function testDeleteTagExpectedException(ISystemTag $tag, $expectedException) { + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($tag->isUserVisible())); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue($tag->isUserAssignable())); $this->tagManager->expects($this->never()) ->method('deleteTags'); $this->tagMapper->expects($this->never()) @@ -110,7 +127,7 @@ class SystemTagMappingNode extends \Test\TestCase { $thrown = null; try { - $this->getMappingNode(false, $tag)->delete(); + $this->getMappingNode($tag)->delete(); } catch (\Exception $e) { $thrown = $e; } @@ -122,11 +139,22 @@ class SystemTagMappingNode extends \Test\TestCase { * @expectedException Sabre\DAV\Exception\NotFound */ public function testDeleteTagNotFound() { + // assuming the tag existed at the time the node was created, + // but got deleted concurrently in the database + $tag = new SystemTag(1, 'Test', true, true); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($tag->isUserVisible())); + $this->tagManager->expects($this->once()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue($tag->isUserAssignable())); $this->tagMapper->expects($this->once()) ->method('unassignTags') ->with(123, 'files', 1) ->will($this->throwException(new TagNotFoundException())); - $this->getMappingNode()->delete(); + $this->getMappingNode($tag)->delete(); } } diff --git a/apps/dav/tests/unit/systemtag/systemtagnode.php b/apps/dav/tests/unit/systemtag/systemtagnode.php index 5184b74e5c8..d9e088a7d90 100644 --- a/apps/dav/tests/unit/systemtag/systemtagnode.php +++ b/apps/dav/tests/unit/systemtag/systemtagnode.php @@ -28,6 +28,7 @@ use Sabre\DAV\Exception\Conflict; use OC\SystemTag\SystemTag; use OCP\SystemTag\TagNotFoundException; use OCP\SystemTag\TagAlreadyExistsException; +use OCP\SystemTag\ISystemTag; class SystemTagNode extends \Test\TestCase { @@ -36,10 +37,16 @@ class SystemTagNode extends \Test\TestCase { */ private $tagManager; + /** + * @var \OCP\IUser + */ + private $user; + protected function setUp() { parent::setUp(); $this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager'); + $this->user = $this->getMock('\OCP\IUser'); } protected function getTagNode($isAdmin = true, $tag = null) { @@ -48,6 +55,7 @@ class SystemTagNode extends \Test\TestCase { } return new \OCA\DAV\SystemTag\SystemTagNode( $tag, + $this->user, $isAdmin, $this->tagManager ); @@ -102,6 +110,14 @@ class SystemTagNode extends \Test\TestCase { */ public function testUpdateTag($isAdmin, $originalTag, $changedArgs) { $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($originalTag) + ->will($this->returnValue($originalTag->isUserVisible() || $isAdmin)); + $this->tagManager->expects($this->once()) + ->method('canUserAssignTag') + ->with($originalTag) + ->will($this->returnValue($originalTag->isUserAssignable() || $isAdmin)); + $this->tagManager->expects($this->once()) ->method('updateTag') ->with(1, $changedArgs[0], $changedArgs[1], $changedArgs[2]); $this->getTagNode($isAdmin, $originalTag) @@ -153,6 +169,14 @@ class SystemTagNode extends \Test\TestCase { * @dataProvider tagNodeProviderPermissionException */ public function testUpdateTagPermissionException($originalTag, $changedArgs, $expectedException = null) { + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($originalTag) + ->will($this->returnValue($originalTag->isUserVisible())); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($originalTag) + ->will($this->returnValue($originalTag->isUserAssignable())); $this->tagManager->expects($this->never()) ->method('updateTag'); @@ -172,32 +196,59 @@ class SystemTagNode extends \Test\TestCase { * @expectedException Sabre\DAV\Exception\Conflict */ public function testUpdateTagAlreadyExists() { + $tag = new SystemTag(1, 'tag1', true, true); + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) ->method('updateTag') - ->with(1, 'Renamed', false, true) + ->with(1, 'Renamed', true, true) ->will($this->throwException(new TagAlreadyExistsException())); - $this->getTagNode()->update('Renamed', false, true); + $this->getTagNode(false, $tag)->update('Renamed', true, true); } /** * @expectedException Sabre\DAV\Exception\NotFound */ public function testUpdateTagNotFound() { + $tag = new SystemTag(1, 'tag1', true, true); + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) ->method('updateTag') - ->with(1, 'Renamed', false, true) + ->with(1, 'Renamed', true, true) ->will($this->throwException(new TagNotFoundException())); - $this->getTagNode()->update('Renamed', false, true); + $this->getTagNode(false, $tag)->update('Renamed', true, true); } /** * @dataProvider adminFlagProvider */ public function testDeleteTag($isAdmin) { + $tag = new SystemTag(1, 'tag1', true, true); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); + $this->tagManager->expects($this->once()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) ->method('deleteTags') ->with('1'); - $this->getTagNode($isAdmin)->delete(); + $this->getTagNode($isAdmin, $tag)->delete(); } public function tagNodeDeleteProviderPermissionException() { @@ -218,7 +269,15 @@ class SystemTagNode extends \Test\TestCase { /** * @dataProvider tagNodeDeleteProviderPermissionException */ - public function testDeleteTagPermissionException($tag, $expectedException) { + public function testDeleteTagPermissionException(ISystemTag $tag, $expectedException) { + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($tag->isUserVisible())); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue($tag->isUserAssignable())); $this->tagManager->expects($this->never()) ->method('deleteTags'); @@ -235,10 +294,19 @@ class SystemTagNode extends \Test\TestCase { * @expectedException Sabre\DAV\Exception\NotFound */ public function testDeleteTagNotFound() { + $tag = new SystemTag(1, 'tag1', true, true); + $this->tagManager->expects($this->any()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($tag->isUserVisible())); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue($tag->isUserAssignable())); $this->tagManager->expects($this->once()) ->method('deleteTags') ->with('1') ->will($this->throwException(new TagNotFoundException())); - $this->getTagNode()->delete(); + $this->getTagNode(false, $tag)->delete(); } } diff --git a/apps/dav/tests/unit/systemtag/systemtagplugin.php b/apps/dav/tests/unit/systemtag/systemtagplugin.php index 4466533f1e0..da82bc8904a 100644 --- a/apps/dav/tests/unit/systemtag/systemtagplugin.php +++ b/apps/dav/tests/unit/systemtag/systemtagplugin.php @@ -27,6 +27,8 @@ use OC\SystemTag\SystemTag; use OCP\IGroupManager; use OCP\IUserSession; use OCP\SystemTag\TagAlreadyExistsException; +use OCP\IUser; +use OCP\SystemTag\ISystemTag; class SystemTagPlugin extends \Test\TestCase { @@ -34,6 +36,8 @@ class SystemTagPlugin extends \Test\TestCase { const DISPLAYNAME_PROPERTYNAME = \OCA\DAV\SystemTag\SystemTagPlugin::DISPLAYNAME_PROPERTYNAME; const USERVISIBLE_PROPERTYNAME = \OCA\DAV\SystemTag\SystemTagPlugin::USERVISIBLE_PROPERTYNAME; const USERASSIGNABLE_PROPERTYNAME = \OCA\DAV\SystemTag\SystemTagPlugin::USERASSIGNABLE_PROPERTYNAME; + const CANASSIGN_PROPERTYNAME = \OCA\DAV\SystemTag\SystemTagPlugin::CANASSIGN_PROPERTYNAME; + const GROUPS_PROPERTYNAME = \OCA\DAV\SystemTag\SystemTagPlugin::GROUPS_PROPERTYNAME; /** * @var \Sabre\DAV\Server @@ -61,6 +65,11 @@ class SystemTagPlugin extends \Test\TestCase { private $userSession; /** + * @var IUser + */ + private $user; + + /** * @var \OCA\DAV\SystemTag\SystemTagPlugin */ private $plugin; @@ -75,7 +84,16 @@ class SystemTagPlugin extends \Test\TestCase { $this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager'); $this->groupManager = $this->getMock('\OCP\IGroupManager'); + $this->user = $this->getMock('\OCP\IUser'); $this->userSession = $this->getMock('\OCP\IUserSession'); + $this->userSession + ->expects($this->any()) + ->method('getUser') + ->willReturn($this->user); + $this->userSession + ->expects($this->any()) + ->method('isLoggedIn') + ->willReturn(true); $this->plugin = new \OCA\DAV\SystemTag\SystemTagPlugin( $this->tagManager, @@ -85,22 +103,84 @@ class SystemTagPlugin extends \Test\TestCase { $this->plugin->initialize($this->server); } - public function testGetProperties() { - $systemTag = new SystemTag(1, 'Test', true, true); - $requestedProperties = [ - self::ID_PROPERTYNAME, - self::DISPLAYNAME_PROPERTYNAME, - self::USERVISIBLE_PROPERTYNAME, - self::USERASSIGNABLE_PROPERTYNAME - ]; - $expectedProperties = [ - 200 => [ - self::ID_PROPERTYNAME => '1', - self::DISPLAYNAME_PROPERTYNAME => 'Test', - self::USERVISIBLE_PROPERTYNAME => 'true', - self::USERASSIGNABLE_PROPERTYNAME => 'true', - ] + public function getPropertiesDataProvider() { + return [ + [ + new SystemTag(1, 'Test', true, true), + [], + [ + self::ID_PROPERTYNAME, + self::DISPLAYNAME_PROPERTYNAME, + self::USERVISIBLE_PROPERTYNAME, + self::USERASSIGNABLE_PROPERTYNAME, + self::CANASSIGN_PROPERTYNAME, + ], + [ + self::ID_PROPERTYNAME => '1', + self::DISPLAYNAME_PROPERTYNAME => 'Test', + self::USERVISIBLE_PROPERTYNAME => 'true', + self::USERASSIGNABLE_PROPERTYNAME => 'true', + self::CANASSIGN_PROPERTYNAME => 'true', + ] + ], + [ + new SystemTag(1, 'Test', true, false), + [], + [ + self::ID_PROPERTYNAME, + self::DISPLAYNAME_PROPERTYNAME, + self::USERVISIBLE_PROPERTYNAME, + self::USERASSIGNABLE_PROPERTYNAME, + self::CANASSIGN_PROPERTYNAME, + ], + [ + self::ID_PROPERTYNAME => '1', + self::DISPLAYNAME_PROPERTYNAME => 'Test', + self::USERVISIBLE_PROPERTYNAME => 'true', + self::USERASSIGNABLE_PROPERTYNAME => 'false', + self::CANASSIGN_PROPERTYNAME => 'false', + ] + ], + [ + new SystemTag(1, 'Test', true, false), + ['group1', 'group2'], + [ + self::ID_PROPERTYNAME, + self::GROUPS_PROPERTYNAME, + ], + [ + self::ID_PROPERTYNAME => '1', + self::GROUPS_PROPERTYNAME => 'group1|group2', + ] + ], + [ + new SystemTag(1, 'Test', true, true), + ['group1', 'group2'], + [ + self::ID_PROPERTYNAME, + self::GROUPS_PROPERTYNAME, + ], + [ + self::ID_PROPERTYNAME => '1', + // groups only returned when userAssignable is false + self::GROUPS_PROPERTYNAME => '', + ] + ], ]; + } + + /** + * @dataProvider getPropertiesDataProvider + */ + public function testGetProperties(ISystemTag $systemTag, $groups, $requestedProperties, $expectedProperties) { + $this->user->expects($this->any()) + ->method('getUID') + ->willReturn('admin'); + $this->groupManager + ->expects($this->any()) + ->method('isAdmin') + ->with('admin') + ->willReturn(true); $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagNode') ->disableOriginalConstructor() @@ -109,6 +189,14 @@ class SystemTagPlugin extends \Test\TestCase { ->method('getSystemTag') ->will($this->returnValue($systemTag)); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->will($this->returnValue($systemTag->isUserAssignable())); + + $this->tagManager->expects($this->any()) + ->method('getTagGroups') + ->will($this->returnValue($groups)); + $this->tree->expects($this->any()) ->method('getNodeForPath') ->with('/systemtag/1') @@ -128,12 +216,62 @@ class SystemTagPlugin extends \Test\TestCase { $result = $propFind->getResultForMultiStatus(); $this->assertEmpty($result[404]); - unset($result[404]); - $this->assertEquals($expectedProperties, $result); + $this->assertEquals($expectedProperties, $result[200]); } - public function testUpdateProperties() { + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testGetPropertiesForbidden() { $systemTag = new SystemTag(1, 'Test', true, false); + $requestedProperties = [ + self::ID_PROPERTYNAME, + self::GROUPS_PROPERTYNAME, + ]; + $this->user->expects($this->once()) + ->method('getUID') + ->willReturn('admin'); + $this->groupManager + ->expects($this->once()) + ->method('isAdmin') + ->with('admin') + ->willReturn(false); + + $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagNode') + ->disableOriginalConstructor() + ->getMock(); + $node->expects($this->any()) + ->method('getSystemTag') + ->will($this->returnValue($systemTag)); + + $this->tree->expects($this->any()) + ->method('getNodeForPath') + ->with('/systemtag/1') + ->will($this->returnValue($node)); + + $propFind = new \Sabre\DAV\PropFind( + '/systemtag/1', + $requestedProperties, + 0 + ); + + $this->plugin->handleGetProperties( + $propFind, + $node + ); + } + + public function testUpdatePropertiesAdmin() { + $systemTag = new SystemTag(1, 'Test', true, false); + $this->user->expects($this->any()) + ->method('getUID') + ->willReturn('admin'); + $this->groupManager + ->expects($this->any()) + ->method('isAdmin') + ->with('admin') + ->willReturn(true); + $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagNode') ->disableOriginalConstructor() ->getMock(); @@ -150,11 +288,16 @@ class SystemTagPlugin extends \Test\TestCase { ->method('update') ->with('Test changed', false, true); + $this->tagManager->expects($this->once()) + ->method('setTagGroups') + ->with($systemTag, ['group1', 'group2']); + // properties to set $propPatch = new \Sabre\DAV\PropPatch(array( self::DISPLAYNAME_PROPERTYNAME => 'Test changed', self::USERVISIBLE_PROPERTYNAME => 'false', self::USERASSIGNABLE_PROPERTYNAME => 'true', + self::GROUPS_PROPERTYNAME => 'group1|group2', )); $this->plugin->handleUpdateProperties( @@ -174,102 +317,89 @@ class SystemTagPlugin extends \Test\TestCase { } /** - * @expectedException \Sabre\DAV\Exception\BadRequest - * @expectedExceptionMessage Not sufficient permissions + * @expectedException \Sabre\DAV\Exception\Forbidden */ - public function testCreateNotAssignableTagAsRegularUser() { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->once()) + public function testUpdatePropertiesForbidden() { + $systemTag = new SystemTag(1, 'Test', true, false); + $this->user->expects($this->any()) ->method('getUID') ->willReturn('admin'); - $this->userSession - ->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession - ->expects($this->once()) - ->method('getUser') - ->willReturn($user); $this->groupManager - ->expects($this->once()) + ->expects($this->any()) ->method('isAdmin') ->with('admin') ->willReturn(false); - $requestData = json_encode([ - 'name' => 'Test', - 'userVisible' => true, - 'userAssignable' => false, - ]); - - $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagsByIdCollection') + $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagNode') ->disableOriginalConstructor() ->getMock(); - $this->tagManager->expects($this->never()) - ->method('createTag'); + $node->expects($this->any()) + ->method('getSystemTag') + ->will($this->returnValue($systemTag)); $this->tree->expects($this->any()) ->method('getNodeForPath') - ->with('/systemtags') + ->with('/systemtag/1') ->will($this->returnValue($node)); - $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface') - ->disableOriginalConstructor() - ->getMock(); + $node->expects($this->never()) + ->method('update'); - $request->expects($this->once()) - ->method('getPath') - ->will($this->returnValue('/systemtags')); + $this->tagManager->expects($this->never()) + ->method('setTagGroups'); - $request->expects($this->once()) - ->method('getBodyAsString') - ->will($this->returnValue($requestData)); + // properties to set + $propPatch = new \Sabre\DAV\PropPatch(array( + self::GROUPS_PROPERTYNAME => 'group1|group2', + )); - $request->expects($this->once()) - ->method('getHeader') - ->with('Content-Type') - ->will($this->returnValue('application/json')); + $this->plugin->handleUpdateProperties( + '/systemtag/1', + $propPatch + ); - $this->plugin->httpPost($request, $response); + $propPatch->commit(); } + public function createTagInsufficientPermissionsProvider() { + return [ + [true, false, ''], + [false, true, ''], + [true, true, 'group1|group2'], + ]; + } /** + * @dataProvider createTagInsufficientPermissionsProvider * @expectedException \Sabre\DAV\Exception\BadRequest * @expectedExceptionMessage Not sufficient permissions */ - public function testCreateInvisibleTagAsRegularUser() { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->once()) + public function testCreateNotAssignableTagAsRegularUser($userVisible, $userAssignable, $groups) { + $this->user->expects($this->once()) ->method('getUID') ->willReturn('admin'); - $this->userSession - ->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession - ->expects($this->once()) - ->method('getUser') - ->willReturn($user); $this->groupManager ->expects($this->once()) ->method('isAdmin') ->with('admin') ->willReturn(false); - $requestData = json_encode([ + $requestData = [ 'name' => 'Test', - 'userVisible' => false, - 'userAssignable' => true, - ]); + 'userVisible' => $userVisible, + 'userAssignable' => $userAssignable, + ]; + if (!empty($groups)) { + $requestData['groups'] = $groups; + } + $requestData = json_encode($requestData); $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagsByIdCollection') ->disableOriginalConstructor() ->getMock(); $this->tagManager->expects($this->never()) ->method('createTag'); + $this->tagManager->expects($this->never()) + ->method('setTagGroups'); $this->tree->expects($this->any()) ->method('getNodeForPath') @@ -352,19 +482,21 @@ class SystemTagPlugin extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - public function testCreateTagInByIdCollection() { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->once()) + public function createTagProvider() { + return [ + [true, false, ''], + [false, false, ''], + [true, false, 'group1|group2'], + ]; + } + + /** + * @dataProvider createTagProvider + */ + public function testCreateTagInByIdCollection($userVisible, $userAssignable, $groups) { + $this->user->expects($this->once()) ->method('getUID') ->willReturn('admin'); - $this->userSession - ->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession - ->expects($this->once()) - ->method('getUser') - ->willReturn($user); $this->groupManager ->expects($this->once()) ->method('isAdmin') @@ -373,19 +505,33 @@ class SystemTagPlugin extends \Test\TestCase { $systemTag = new SystemTag(1, 'Test', true, false); - $requestData = json_encode([ + $requestData = [ 'name' => 'Test', - 'userVisible' => true, - 'userAssignable' => false, - ]); + 'userVisible' => $userVisible, + 'userAssignable' => $userAssignable, + ]; + if (!empty($groups)) { + $requestData['groups'] = $groups; + } + $requestData = json_encode($requestData); $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagsByIdCollection') ->disableOriginalConstructor() ->getMock(); $this->tagManager->expects($this->once()) ->method('createTag') - ->with('Test', true, false) + ->with('Test', $userVisible, $userAssignable) ->will($this->returnValue($systemTag)); + + if (!empty($groups)) { + $this->tagManager->expects($this->once()) + ->method('setTagGroups') + ->with($systemTag, explode('|', $groups)) + ->will($this->returnValue($systemTag)); + } else { + $this->tagManager->expects($this->never()) + ->method('setTagGroups'); + } $this->tree->expects($this->any()) ->method('getNodeForPath') @@ -431,18 +577,9 @@ class SystemTagPlugin extends \Test\TestCase { } public function testCreateTagInMappingCollection() { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->once()) + $this->user->expects($this->once()) ->method('getUID') ->willReturn('admin'); - $this->userSession - ->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession - ->expects($this->once()) - ->method('getUser') - ->willReturn($user); $this->groupManager ->expects($this->once()) ->method('isAdmin') @@ -510,8 +647,6 @@ class SystemTagPlugin extends \Test\TestCase { * @expectedException \Sabre\DAV\Exception\NotFound */ public function testCreateTagToUnknownNode() { - $systemTag = new SystemTag(1, 'Test', true, false); - $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagsObjectMappingCollection') ->disableOriginalConstructor() ->getMock(); @@ -545,18 +680,9 @@ class SystemTagPlugin extends \Test\TestCase { * @expectedException \Sabre\DAV\Exception\Conflict */ public function testCreateTagConflict($nodeClass) { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->once()) + $this->user->expects($this->once()) ->method('getUID') ->willReturn('admin'); - $this->userSession - ->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession - ->expects($this->once()) - ->method('getUser') - ->willReturn($user); $this->groupManager ->expects($this->once()) ->method('isAdmin') diff --git a/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php b/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php index a2bf571ab68..5aa28d1a254 100644 --- a/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php +++ b/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php @@ -32,6 +32,11 @@ class SystemTagsByIdCollection extends \Test\TestCase { */ private $tagManager; + /** + * @var \OCP\IUser + */ + private $user; + protected function setUp() { parent::setUp(); @@ -39,14 +44,14 @@ class SystemTagsByIdCollection extends \Test\TestCase { } public function getNode($isAdmin = true) { - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->any()) + $this->user = $this->getMock('\OCP\IUser'); + $this->user->expects($this->any()) ->method('getUID') ->will($this->returnValue('testuser')); $userSession = $this->getMock('\OCP\IUserSession'); $userSession->expects($this->any()) ->method('getUser') - ->will($this->returnValue($user)); + ->will($this->returnValue($this->user)); $groupManager = $this->getMock('\OCP\IGroupManager'); $groupManager->expects($this->any()) ->method('isAdmin') @@ -77,35 +82,19 @@ class SystemTagsByIdCollection extends \Test\TestCase { $this->getNode()->createDirectory('789'); } - public function getChildProvider() { - return [ - [ - true, - true, - ], - [ - true, - false, - ], - [ - false, - true, - ], - ]; - } - - /** - * @dataProvider getChildProvider - */ - public function testGetChild($isAdmin, $userVisible) { - $tag = new SystemTag(123, 'Test', $userVisible, false); + public function testGetChild() { + $tag = new SystemTag(123, 'Test', true, false); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) ->method('getTagsByIds') ->with(['123']) ->will($this->returnValue([$tag])); - $childNode = $this->getNode($isAdmin)->getChild('123'); + $childNode = $this->getNode()->getChild('123'); $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagNode', $childNode); $this->assertEquals('123', $childNode->getName()); @@ -198,27 +187,27 @@ class SystemTagsByIdCollection extends \Test\TestCase { public function childExistsProvider() { return [ - // admins, always visible - [true, true, true], - [true, false, true], - // non-admins, depends on flag - [false, true, true], - [false, false, false], + [true, true], + [false, false], ]; } /** * @dataProvider childExistsProvider */ - public function testChildExists($isAdmin, $userVisible, $expectedResult) { + public function testChildExists($userVisible, $expectedResult) { $tag = new SystemTag(123, 'One', $userVisible, false); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($userVisible)); $this->tagManager->expects($this->once()) ->method('getTagsByIds') ->with(['123']) ->will($this->returnValue([$tag])); - $this->assertEquals($expectedResult, $this->getNode($isAdmin)->childExists('123')); + $this->assertEquals($expectedResult, $this->getNode()->childExists('123')); } public function testChildExistsNotFound() { diff --git a/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php b/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php index df97acd846b..9adc5b88c41 100644 --- a/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php +++ b/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php @@ -37,45 +37,50 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { */ private $tagMapper; + /** + * @var \OCP\IUser + */ + private $user; + protected function setUp() { parent::setUp(); $this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager'); $this->tagMapper = $this->getMock('\OCP\SystemTag\ISystemTagObjectMapper'); + + $this->user = $this->getMock('\OCP\IUser'); } - public function getNode($isAdmin = true) { + public function getNode() { return new \OCA\DAV\SystemTag\SystemTagsObjectMappingCollection ( 111, 'files', - $isAdmin, + $this->user, $this->tagManager, $this->tagMapper ); } - public function testAssignTagAsAdmin() { - $this->tagManager->expects($this->never()) - ->method('getTagsByIds'); - $this->tagMapper->expects($this->once()) - ->method('assignTags') - ->with(111, 'files', '555'); - - $this->getNode(true)->createFile('555'); - } - - public function testAssignTagAsUser() { + public function testAssignTag() { $tag = new SystemTag('1', 'Test', true, true); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); + $this->tagManager->expects($this->once()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) ->method('getTagsByIds') - ->with('555') + ->with(['555']) ->will($this->returnValue([$tag])); $this->tagMapper->expects($this->once()) ->method('assignTags') ->with(111, 'files', '555'); - $this->getNode(false)->createFile('555'); + $this->getNode()->createFile('555'); } public function permissionsProvider() { @@ -90,19 +95,27 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { /** * @dataProvider permissionsProvider */ - public function testAssignTagAsUserNoPermission($userVisible, $userAssignable, $expectedException) { + public function testAssignTagNoPermission($userVisible, $userAssignable, $expectedException) { $tag = new SystemTag('1', 'Test', $userVisible, $userAssignable); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue($userVisible)); + $this->tagManager->expects($this->any()) + ->method('canUserAssignTag') + ->with($tag) + ->will($this->returnValue($userAssignable)); $this->tagManager->expects($this->once()) ->method('getTagsByIds') - ->with('555') + ->with(['555']) ->will($this->returnValue([$tag])); $this->tagMapper->expects($this->never()) ->method('assignTags'); $thrown = null; try { - $this->getNode(false)->createFile('555'); + $this->getNode()->createFile('555'); } catch (\Exception $e) { $thrown = $e; } @@ -114,9 +127,9 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { * @expectedException Sabre\DAV\Exception\PreconditionFailed */ public function testAssignTagNotFound() { - $this->tagMapper->expects($this->once()) - ->method('assignTags') - ->with(111, 'files', '555') + $this->tagManager->expects($this->once()) + ->method('getTagsByIds') + ->with(['555']) ->will($this->throwException(new TagNotFoundException())); $this->getNode()->createFile('555'); @@ -129,28 +142,12 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { $this->getNode()->createDirectory('789'); } - public function getChildProvider() { - return [ - [ - true, - true, - ], - [ - true, - false, - ], - [ - false, - true, - ], - ]; - } - - /** - * @dataProvider getChildProvider - */ - public function testGetChild($isAdmin, $userVisible) { - $tag = new SystemTag(555, 'TheTag', $userVisible, false); + public function testGetChild() { + $tag = new SystemTag(555, 'TheTag', true, false); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); $this->tagMapper->expects($this->once()) ->method('haveTag') @@ -162,17 +159,21 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { ->with(['555']) ->will($this->returnValue(['555' => $tag])); - $childNode = $this->getNode($isAdmin)->getChild('555'); + $childNode = $this->getNode()->getChild('555'); - $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagNode', $childNode); + $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $childNode); $this->assertEquals('555', $childNode->getName()); } /** * @expectedException \Sabre\DAV\Exception\NotFound */ - public function testGetChildUserNonVisible() { + public function testGetChildNonVisible() { $tag = new SystemTag(555, 'TheTag', false, false); + $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(false)); $this->tagMapper->expects($this->once()) ->method('haveTag') @@ -184,7 +185,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { ->with(['555']) ->will($this->returnValue(['555' => $tag])); - $this->getNode(false)->getChild('555'); + $this->getNode()->getChild('555'); } /** @@ -223,7 +224,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { $this->getNode()->getChild('777'); } - public function testGetChildrenAsAdmin() { + public function testGetChildren() { $tag1 = new SystemTag(555, 'TagOne', true, false); $tag2 = new SystemTag(556, 'TagTwo', true, true); $tag3 = new SystemTag(557, 'InvisibleTag', false, true); @@ -238,43 +239,13 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { ->with(['555', '556', '557']) ->will($this->returnValue(['555' => $tag1, '556' => $tag2, '557' => $tag3])); - $children = $this->getNode(true)->getChildren(); - - $this->assertCount(3, $children); - - $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[0]); - $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[1]); - $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[2]); - - $this->assertEquals(111, $children[0]->getObjectId()); - $this->assertEquals('files', $children[0]->getObjectType()); - $this->assertEquals($tag1, $children[0]->getSystemTag()); - - $this->assertEquals(111, $children[1]->getObjectId()); - $this->assertEquals('files', $children[1]->getObjectType()); - $this->assertEquals($tag2, $children[1]->getSystemTag()); + $this->tagManager->expects($this->exactly(3)) + ->method('canUserSeeTag') + ->will($this->returnCallback(function($tag) { + return $tag->isUserVisible(); + })); - $this->assertEquals(111, $children[2]->getObjectId()); - $this->assertEquals('files', $children[2]->getObjectType()); - $this->assertEquals($tag3, $children[2]->getSystemTag()); - } - - public function testGetChildrenAsUser() { - $tag1 = new SystemTag(555, 'TagOne', true, false); - $tag2 = new SystemTag(556, 'TagTwo', true, true); - $tag3 = new SystemTag(557, 'InvisibleTag', false, true); - - $this->tagMapper->expects($this->once()) - ->method('getTagIdsForObjects') - ->with([111], 'files') - ->will($this->returnValue(['111' => ['555', '556', '557']])); - - $this->tagManager->expects($this->once()) - ->method('getTagsByIds') - ->with(['555', '556', '557']) - ->will($this->returnValue(['555' => $tag1, '556' => $tag2, '557' => $tag3])); - - $children = $this->getNode(false)->getChildren(); + $children = $this->getNode()->getChildren(); $this->assertCount(2, $children); @@ -290,16 +261,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { $this->assertEquals($tag2, $children[1]->getSystemTag()); } - public function testChildExistsAsAdmin() { - $this->tagMapper->expects($this->once()) - ->method('haveTag') - ->with([111], 'files', '555') - ->will($this->returnValue(true)); - - $this->assertTrue($this->getNode(true)->childExists('555')); - } - - public function testChildExistsWithVisibleTagAsUser() { + public function testChildExistsWithVisibleTag() { $tag = new SystemTag(555, 'TagOne', true, false); $this->tagMapper->expects($this->once()) @@ -308,14 +270,19 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { ->will($this->returnValue(true)); $this->tagManager->expects($this->once()) + ->method('canUserSeeTag') + ->with($tag) + ->will($this->returnValue(true)); + + $this->tagManager->expects($this->once()) ->method('getTagsByIds') - ->with('555') + ->with(['555']) ->will($this->returnValue([$tag])); - $this->assertTrue($this->getNode(false)->childExists('555')); + $this->assertTrue($this->getNode()->childExists('555')); } - public function testChildExistsWithInvisibleTagAsUser() { + public function testChildExistsWithInvisibleTag() { $tag = new SystemTag(555, 'TagOne', false, false); $this->tagMapper->expects($this->once()) @@ -325,10 +292,10 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase { $this->tagManager->expects($this->once()) ->method('getTagsByIds') - ->with('555') + ->with(['555']) ->will($this->returnValue([$tag])); - $this->assertFalse($this->getNode(false)->childExists('555')); + $this->assertFalse($this->getNode()->childExists('555')); } public function testChildExistsNotFound() { diff --git a/apps/systemtags/js/systemtagsinfoview.js b/apps/systemtags/js/systemtagsinfoview.js index 2f01ca7db34..a7320a3956f 100644 --- a/apps/systemtags/js/systemtagsinfoview.js +++ b/apps/systemtags/js/systemtagsinfoview.js @@ -12,7 +12,7 @@ function modelToSelection(model) { var data = model.toJSON(); - if (!OC.isUserAdmin() && !data.userAssignable) { + if (!OC.isUserAdmin() && !data.canAssign) { data.locked = true; } return data; diff --git a/apps/systemtags/lib/Activity/Extension.php b/apps/systemtags/lib/Activity/Extension.php index 8c101a6f550..6bb83e37cfc 100644 --- a/apps/systemtags/lib/Activity/Extension.php +++ b/apps/systemtags/lib/Activity/Extension.php @@ -324,7 +324,7 @@ class Extension implements IExtension { case 'assignable': return '<parameter>' . $matches[1] . '</parameter>'; case 'not-assignable': - return '<parameter>' . $l->t('%s (not-assignable)', $matches[1]) . '</parameter>'; + return '<parameter>' . $l->t('%s (restricted)', $matches[1]) . '</parameter>'; case 'invisible': return '<parameter>' . $l->t('%s (invisible)', $matches[1]) . '</parameter>'; } diff --git a/apps/systemtags/tests/js/systemtagsinfoviewSpec.js b/apps/systemtags/tests/js/systemtagsinfoviewSpec.js index 27724822c2e..449dfd859d7 100644 --- a/apps/systemtags/tests/js/systemtagsinfoviewSpec.js +++ b/apps/systemtags/tests/js/systemtagsinfoviewSpec.js @@ -62,9 +62,9 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { fetchStub.yieldTo('success', view.selectedTagsCollection); expect(setDataStub.calledOnce).toEqual(true); expect(setDataStub.getCall(0).args[0]).toEqual([{ - id: '1', name: 'test1', userVisible: true, userAssignable: true + id: '1', name: 'test1', userVisible: true, userAssignable: true, canAssign: true }, { - id: '3', name: 'test3', userVisible: true, userAssignable: true + id: '3', name: 'test3', userVisible: true, userAssignable: true, canAssign: true }]); expect(view.$el.hasClass('hidden')).toEqual(false); @@ -79,7 +79,7 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { view = new OCA.SystemTags.SystemTagsInfoView(); view.selectedTagsCollection.add([ {id: '1', name: 'test1'}, - {id: '3', name: 'test3', userVisible: false, userAssignable: false} + {id: '3', name: 'test3', userVisible: false, userAssignable: false, canAssign: false} ]); var callback = sinon.stub(); @@ -87,9 +87,9 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { expect(callback.calledOnce).toEqual(true); expect(callback.getCall(0).args[0]).toEqual([{ - id: '1', name: 'test1', userVisible: true, userAssignable: true + id: '1', name: 'test1', userVisible: true, userAssignable: true, canAssign: true }, { - id: '3', name: 'test3', userVisible: false, userAssignable: false + id: '3', name: 'test3', userVisible: false, userAssignable: false, canAssign: false }]); inputViewSpy.restore(); @@ -103,7 +103,7 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { view = new OCA.SystemTags.SystemTagsInfoView(); view.selectedTagsCollection.add([ {id: '1', name: 'test1'}, - {id: '3', name: 'test3', userAssignable: false} + {id: '3', name: 'test3', userAssignable: false, canAssign: false} ]); var callback = sinon.stub(); @@ -111,9 +111,33 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { expect(callback.calledOnce).toEqual(true); expect(callback.getCall(0).args[0]).toEqual([{ - id: '1', name: 'test1', userVisible: true, userAssignable: true + id: '1', name: 'test1', userVisible: true, userAssignable: true, canAssign: true }, { - id: '3', name: 'test3', userVisible: true, userAssignable: false, locked: true + id: '3', name: 'test3', userVisible: true, userAssignable: false, canAssign: false, locked: true + }]); + + inputViewSpy.restore(); + }); + it('does not set locked flag on non-assignable tags when canAssign overrides it with true', function() { + isAdminStub.returns(false); + + var inputViewSpy = sinon.spy(OC.SystemTags, 'SystemTagsInputField'); + var element = $('<input type="hidden" val="1,4"/>'); + view.remove(); + view = new OCA.SystemTags.SystemTagsInfoView(); + view.selectedTagsCollection.add([ + {id: '1', name: 'test1'}, + {id: '4', name: 'test4', userAssignable: false, canAssign: true} + ]); + + var callback = sinon.stub(); + inputViewSpy.getCall(0).args[0].initSelection(element, callback); + + expect(callback.calledOnce).toEqual(true); + expect(callback.getCall(0).args[0]).toEqual([{ + id: '1', name: 'test1', userVisible: true, userAssignable: true, canAssign: true + }, { + id: '4', name: 'test4', userVisible: true, userAssignable: false, canAssign: true }]); inputViewSpy.restore(); @@ -152,7 +176,8 @@ describe('OCA.SystemTags.SystemTagsInfoView tests', function() { id: '2', name: 'test2', userVisible: true, - userAssignable: true + userAssignable: true, + canAssign: true }); createStub.restore(); |