Example #1
0
 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'));
 }
Example #5
0
 /**
  * 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);
     }
 }
Example #6
0
 /**
  * @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);
         }
     }
 }
Example #7
0
 /**
  * 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();
 }
Example #9
0
 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);
 }
Example #14
0
 /**
  * @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);
     }
 }
Example #18
0
 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());
 }
Example #21
0
 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;
     }
 }
Example #23
0
 /**
  * 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;
     });
 }
Example #26
0
 /**
  * @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');
 }
Example #28
0
 public function testDeleteTag()
 {
     $this->tagManager->expects($this->never())->method('deleteTags');
     $this->tagMapper->expects($this->once())->method('unassignTags')->with(123, 'files', 1);
     $this->node->delete();
 }