public function setUp() { parent::setUp(); $this->connection = \OC::$server->getDatabaseConnection(); $this->pruneTagsTables(); $this->tagManager = $this->getMockBuilder('OCP\\SystemTag\\ISystemTagManager')->getMock(); $this->tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager); $this->tag1 = new SystemTag(1, 'testtag1', false, false); $this->tag2 = new SystemTag(2, 'testtag2', true, false); $this->tag3 = new SystemTag(3, 'testtag3', false, false); $this->tagManager->expects($this->any())->method('getTagsByIds')->will($this->returnCallback(function ($tagIds) { $result = []; if (in_array(1, $tagIds)) { $result[1] = $this->tag1; } if (in_array(2, $tagIds)) { $result[2] = $this->tag2; } if (in_array(3, $tagIds)) { $result[3] = $this->tag3; } return $result; })); $this->tagMapper->assignTags(1, 'testtype', $this->tag1->getId()); $this->tagMapper->assignTags(1, 'testtype', $this->tag2->getId()); $this->tagMapper->assignTags(2, 'testtype', $this->tag1->getId()); $this->tagMapper->assignTags(3, 'anothertype', $this->tag1->getId()); }
function childExists($name) { try { $this->tagManager->getTagsByIds([$name]); return true; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { return false; } }
/** * @dataProvider tagNodeDeleteProviderPermissionException */ public function testDeleteTagExpectedException($tag, $expectedException) { $this->tagManager->expects($this->never())->method('deleteTags'); $this->tagMapper->expects($this->never())->method('unassignTags'); $thrown = null; try { $this->getMappingNode(false, $tag)->delete(); } catch (\Exception $e) { $thrown = $e; } $this->assertInstanceOf($expectedException, $thrown); }
public function testChildExistsWithInvisibleTag() { $tag = new SystemTag(555, 'TagOne', false, false); $this->tagMapper->expects($this->once())->method('haveTag')->with([111], 'files', '555')->will($this->returnValue(true)); $this->tagManager->expects($this->once())->method('getTagsByIds')->with(['555'])->will($this->returnValue([$tag])); $this->assertFalse($this->getNode()->childExists('555')); }
/** * Creates a new tag * * @param string $data JSON encoded string containing the properties of the tag to create * @param string $contentType content type of the data * @return ISystemTag newly created system tag * * @throws BadRequest if a field was missing * @throws Conflict if a tag with the same properties already exists * @throws UnsupportedMediaType if the content type is not supported */ private function createTag($data, $contentType = 'application/json') { if (explode(';', $contentType)[0] === 'application/json') { $data = json_decode($data, true); } else { throw new UnsupportedMediaType(); } if (!isset($data['name'])) { throw new BadRequest('Missing "name" attribute'); } $tagName = $data['name']; $userVisible = true; $userAssignable = true; if (isset($data['userVisible'])) { $userVisible = (bool) $data['userVisible']; } if (isset($data['userAssignable'])) { $userAssignable = (bool) $data['userAssignable']; } try { return $this->tagManager->createTag($tagName, $userVisible, $userAssignable); } catch (TagAlreadyExistsException $e) { throw new Conflict('Tag already exists', 0, $e); } }
/** * @param MapperEvent $event */ public function mapperEvent(MapperEvent $event) { $tagIds = $event->getTags(); if ($event->getObjectType() !== 'files' || empty($tagIds) || !in_array($event->getEvent(), [MapperEvent::EVENT_ASSIGN, MapperEvent::EVENT_UNASSIGN]) || !$this->appManager->isInstalled('activity')) { // System tags not for files, no tags, not (un-)assigning or no activity-app enabled (save the energy) return; } try { $tags = $this->tagManager->getTagsByIds($tagIds); } catch (TagNotFoundException $e) { // User assigned/unassigned a non-existing tag, ignore... return; } if (empty($tags)) { return; } // Get all mount point owners $cache = $this->mountCollection->getMountCache(); $mounts = $cache->getMountsForFileId($event->getObjectId()); if (empty($mounts)) { return; } $users = []; foreach ($mounts as $mount) { $owner = $mount->getUser()->getUID(); $ownerFolder = $this->rootFolder->getUserFolder($owner); $nodes = $ownerFolder->getById($event->getObjectId()); if (!empty($nodes)) { /** @var Node $node */ $node = array_shift($nodes); $path = $node->getPath(); if (strpos($path, '/' . $owner . '/files/') === 0) { $path = substr($path, strlen('/' . $owner . '/files')); } // Get all users that have access to the mount point $users = array_merge($users, Share::getUsersSharingFile($path, $owner, true, true)); } } $actor = $this->session->getUser(); if ($actor instanceof IUser) { $actor = $actor->getUID(); } else { $actor = ''; } $activity = $this->activityManager->generateEvent(); $activity->setApp(Extension::APP_NAME)->setType(Extension::APP_NAME)->setAuthor($actor)->setObject($event->getObjectType(), $event->getObjectId()); foreach ($users as $user => $path) { $activity->setAffectedUser($user); foreach ($tags as $tag) { if ($event->getEvent() === MapperEvent::EVENT_ASSIGN) { $activity->setSubject(Extension::ASSIGN_TAG, [$actor, $path, $this->prepareTagAsParameter($tag)]); } else { if ($event->getEvent() === MapperEvent::EVENT_UNASSIGN) { $activity->setSubject(Extension::UNASSIGN_TAG, [$actor, $path, $this->prepareTagAsParameter($tag)]); } } $this->activityManager->publish($activity); } } }
/** * Creates a new tag * * @param string $data JSON encoded string containing the properties of the tag to create * @param string $contentType content type of the data * @return ISystemTag newly created system tag * * @throws BadRequest if a field was missing * @throws Conflict if a tag with the same properties already exists * @throws UnsupportedMediaType if the content type is not supported */ private function createTag($data, $contentType = 'application/json') { if (explode(';', $contentType)[0] === 'application/json') { $data = json_decode($data, true); } else { throw new UnsupportedMediaType(); } if (!isset($data['name'])) { throw new BadRequest('Missing "name" attribute'); } $tagName = $data['name']; $userVisible = true; $userAssignable = true; if (isset($data['userVisible'])) { $userVisible = (bool) $data['userVisible']; } if (isset($data['userAssignable'])) { $userAssignable = (bool) $data['userAssignable']; } if ($userVisible === false || $userAssignable === false) { 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); } catch (TagAlreadyExistsException $e) { throw new Conflict('Tag already exists', 0, $e); } }
/** * @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(false, $tag)->delete(); }
public function delete() { try { $this->tagManager->deleteTags($this->tag->getId()); } catch (TagNotFoundException $e) { // can happen if concurrent deletion occurred throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found', 0, $e); } }
/** * @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($tag)->delete(); }
function getChildren() { $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); if (empty($tagIds)) { return []; } $tags = $this->tagManager->getTagsByIds($tagIds); return array_values(array_map(function ($tag) { return $this->makeNode($tag); }, $tags)); }
/** * Asserts that all the given tag ids exist. * * @param string[] $tagIds tag ids to check * * @throws \OCP\SystemTag\TagNotFoundException if at least one tag did not exist */ private function assertTagsExist($tagIds) { $tags = $this->tagManager->getTagsByIds($tagIds); if (count($tags) !== count($tagIds)) { // at least one tag missing, bail out $foundTagIds = array_map(function (ISystemTag $tag) { return $tag->getId(); }, $tags); $missingTagIds = array_diff($tagIds, $foundTagIds); throw new TagNotFoundException('Tags not found', 0, null, $missingTagIds); } }
public function testDeleteTagRemovesRelations() { $tag1 = $this->tagManager->createTag('one', true, false); $tag2 = $this->tagManager->createTag('two', true, true); $tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager); $tagMapper->assignTags(1, 'testtype', $tag1->getId()); $tagMapper->assignTags(1, 'testtype', $tag2->getId()); $tagMapper->assignTags(2, 'testtype', $tag1->getId()); $this->tagManager->deleteTags($tag1->getId()); $tagIdMapping = $tagMapper->getTagIdsForObjects([1, 2], 'testtype'); $this->assertEquals([1 => [$tag2->getId()], 2 => []], $tagIdMapping); }
/** * @dataProvider nodeClassProvider * @expectedException Sabre\DAV\Exception\Conflict */ public function testCreateTagConflict($nodeClass) { $requestData = json_encode(['name' => 'Test', 'userVisible' => true, 'userAssignable' => false]); $node = $this->getMockBuilder($nodeClass)->disableOriginalConstructor()->getMock(); $this->tagManager->expects($this->once())->method('createTag')->with('Test', true, false)->will($this->throwException(new TagAlreadyExistsException('Tag already exists'))); $this->tree->expects($this->any())->method('getNodeForPath')->with('/systemtags')->will($this->returnValue($node)); $request = $this->getMockBuilder('Sabre\\HTTP\\RequestInterface')->disableOriginalConstructor()->getMock(); $response = $this->getMockBuilder('Sabre\\HTTP\\ResponseInterface')->disableOriginalConstructor()->getMock(); $request->expects($this->once())->method('getPath')->will($this->returnValue('/systemtags')); $request->expects($this->once())->method('getBodyAsString')->will($this->returnValue($requestData)); $request->expects($this->once())->method('getHeader')->with('Content-Type')->will($this->returnValue('application/json')); $this->plugin->httpPost($request, $response); }
public function testTagGroups() { $tag1 = $this->tagManager->createTag('tag1', true, false); $tag2 = $this->tagManager->createTag('tag2', true, false); $this->tagManager->setTagGroups($tag1, ['group1', 'group2']); $this->tagManager->setTagGroups($tag2, ['group2', 'group3']); $this->assertEquals(['group1', 'group2'], $this->tagManager->getTagGroups($tag1)); $this->assertEquals(['group2', 'group3'], $this->tagManager->getTagGroups($tag2)); // change groups $this->tagManager->setTagGroups($tag1, ['group3', 'group4']); $this->tagManager->setTagGroups($tag2, []); $this->assertEquals(['group3', 'group4'], $this->tagManager->getTagGroups($tag1)); $this->assertEquals([], $this->tagManager->getTagGroups($tag2)); }
/** * @param string $name */ function childExists($name) { try { $tag = $this->tagManager->getTagsByIds([$name]); $tag = current($tag); if (!$this->isAdmin() && !$tag->isUserVisible()) { return false; } return true; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { return false; } }
/** * Delete tag to object association */ public function delete() { try { 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) { // can happen if concurrent deletion occurred throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found', 0, $e); } }
public function testProcessFilterRulesVisibleTagAsUser() { $this->groupManager->expects($this->any())->method('isAdmin')->will($this->returnValue(false)); $tag1 = $this->getMock('\\OCP\\SystemTag\\ISystemTag'); $tag1->expects($this->any())->method('getId')->will($this->returnValue('123')); $tag1->expects($this->any())->method('isUserVisible')->will($this->returnValue(true)); $tag2 = $this->getMock('\\OCP\\SystemTag\\ISystemTag'); $tag2->expects($this->any())->method('getId')->will($this->returnValue('123')); $tag2->expects($this->any())->method('isUserVisible')->will($this->returnValue(true)); $this->tagManager->expects($this->once())->method('getTagsByIds')->with(['123', '456'])->will($this->returnValue([$tag1, $tag2])); $this->tagMapper->expects($this->at(0))->method('getObjectIdsForTags')->with('123')->will($this->returnValue(['111', '222'])); $this->tagMapper->expects($this->at(1))->method('getObjectIdsForTags')->with('456')->will($this->returnValue(['222', '333'])); $rules = [['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456']]; $this->assertEquals(['222'], array_values($this->invokePrivate($this->plugin, 'processFilterRules', [$rules]))); }
/** * @param string $name */ function childExists($name) { try { $tag = $this->tagManager->getTagsByIds([$name]); $tag = current($tag); if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { return false; } return true; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { return false; } }
public function testGetChildren() { $tag1 = new SystemTag(555, 'TagOne', true, false); $tag2 = new SystemTag(556, 'TagTwo', true, true); $this->tagMapper->expects($this->once())->method('getTagIdsForObjects')->with([111], 'files')->will($this->returnValue(['111' => ['555', '556']])); $this->tagManager->expects($this->once())->method('getTagsByIds')->with(['555', '556'])->will($this->returnValue(['555' => $tag1, '666' => $tag2])); $children = $this->node->getChildren(); $this->assertCount(2, $children); $this->assertInstanceOf('\\OCA\\DAV\\SystemTag\\SystemTagMappingNode', $children[0]); $this->assertInstanceOf('\\OCA\\DAV\\SystemTag\\SystemTagMappingNode', $children[1]); $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()); }
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()); } } $this->tagManager->deleteTags($this->tag->getId()); } catch (TagNotFoundException $e) { // can happen if concurrent deletion occurred throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found', 0, $e); } }
function childExists($tagId) { try { $result = $this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true); if ($result) { $tags = $this->tagManager->getTagsByIds([$tagId]); $tag = current($tags); if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { return false; } } return $result; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { return false; } }
/** * Find file ids matching the given filter rules * * @param array $filterRules * @return array array of unique file id results * * @throws TagNotFoundException whenever a tag was not found */ public function processFilterRules($filterRules) { $ns = '{' . $this::NS_OWNCLOUD . '}'; $resultFileIds = null; $systemTagIds = []; foreach ($filterRules as $filterRule) { if ($filterRule['name'] === $ns . 'systemtag') { $systemTagIds[] = $filterRule['value']; } } // check user permissions, if applicable if (!$this->isAdmin()) { // check visibility/permission $tags = $this->tagManager->getTagsByIds($systemTagIds); $unknownTagIds = []; foreach ($tags as $tag) { if (!$tag->isUserVisible()) { $unknownTagIds[] = $tag->getId(); } } if (!empty($unknownTagIds)) { throw new TagNotFoundException('Tag with ids ' . implode(', ', $unknownTagIds) . ' not found'); } } // fetch all file ids and intersect them foreach ($systemTagIds as $systemTagId) { $fileIds = $this->tagMapper->getObjectIdsForTags($systemTagId, 'files'); if (empty($fileIds)) { // This tag has no files, nothing can ever show up return []; } // first run ? if ($resultFileIds === null) { $resultFileIds = $fileIds; } else { $resultFileIds = array_intersect($resultFileIds, $fileIds); } if (empty($resultFileIds)) { // Empty intersection, nothing can show up anymore return []; } } return $resultFileIds; }
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; } return true; } catch (\InvalidArgumentException $e) { throw new BadRequest('Invalid tag id', 0, $e); } catch (TagNotFoundException $e) { return false; } }
/** * Updates tag attributes * * @param string $path * @param PropPatch $propPatch * * @return void */ public function handleUpdateProperties($path, PropPatch $propPatch) { $propPatch->handle([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) { return; } $tag = $node->getSystemTag(); $name = $tag->getName(); $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); } return true; }); }
/** * @expectedException Sabre\DAV\Exception\NotFound */ public function testDeleteTagNotFound() { $this->tagManager->expects($this->once())->method('deleteTags')->with('1')->will($this->throwException(new TagNotFoundException())); $this->getTagNode()->delete(); }
/** * @expectedException Sabre\DAV\Exception\BadRequest */ public function testChildExistsBadRequest() { $this->tagManager->expects($this->once())->method('getTagsByIds')->with(['invalid'])->will($this->throwException(new \InvalidArgumentException())); $this->node->childExists('invalid'); }
public function testDeleteTag() { $this->tagManager->expects($this->never())->method('deleteTags'); $this->tagMapper->expects($this->once())->method('unassignTags')->with(123, 'files', 1); $this->node->delete(); }