1<?php 2/** 3 * @copyright Copyright (c) 2016, ownCloud, Inc. 4 * 5 * @author Christoph Wurst <christoph@winzerhof-wurst.at> 6 * @author Joas Schilling <coding@schilljs.com> 7 * @author Morris Jobke <hey@morrisjobke.de> 8 * @author Roeland Jago Douma <roeland@famdouma.nl> 9 * @author Vincent Petry <vincent@nextcloud.com> 10 * 11 * @license AGPL-3.0 12 * 13 * This code is free software: you can redistribute it and/or modify 14 * it under the terms of the GNU Affero General Public License, version 3, 15 * as published by the Free Software Foundation. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Affero General Public License for more details. 21 * 22 * You should have received a copy of the GNU Affero General Public License, version 3, 23 * along with this program. If not, see <http://www.gnu.org/licenses/> 24 * 25 */ 26namespace OCA\DAV\SystemTag; 27 28use OCP\IUser; 29use OCP\SystemTag\ISystemTag; 30use OCP\SystemTag\ISystemTagManager; 31use OCP\SystemTag\ISystemTagObjectMapper; 32use OCP\SystemTag\TagNotFoundException; 33use Sabre\DAV\Exception\BadRequest; 34use Sabre\DAV\Exception\Forbidden; 35use Sabre\DAV\Exception\NotFound; 36use Sabre\DAV\Exception\PreconditionFailed; 37use Sabre\DAV\ICollection; 38 39/** 40 * Collection containing tags by object id 41 */ 42class SystemTagsObjectMappingCollection implements ICollection { 43 44 /** 45 * @var string 46 */ 47 private $objectId; 48 49 /** 50 * @var string 51 */ 52 private $objectType; 53 54 /** 55 * @var ISystemTagManager 56 */ 57 private $tagManager; 58 59 /** 60 * @var ISystemTagObjectMapper 61 */ 62 private $tagMapper; 63 64 /** 65 * User 66 * 67 * @var IUser 68 */ 69 private $user; 70 71 72 /** 73 * Constructor 74 * 75 * @param string $objectId object id 76 * @param string $objectType object type 77 * @param IUser $user user 78 * @param ISystemTagManager $tagManager tag manager 79 * @param ISystemTagObjectMapper $tagMapper tag mapper 80 */ 81 public function __construct( 82 $objectId, 83 $objectType, 84 IUser $user, 85 ISystemTagManager $tagManager, 86 ISystemTagObjectMapper $tagMapper 87 ) { 88 $this->tagManager = $tagManager; 89 $this->tagMapper = $tagMapper; 90 $this->objectId = $objectId; 91 $this->objectType = $objectType; 92 $this->user = $user; 93 } 94 95 public function createFile($name, $data = null) { 96 $tagId = $name; 97 try { 98 $tags = $this->tagManager->getTagsByIds([$tagId]); 99 $tag = current($tags); 100 if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { 101 throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); 102 } 103 if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { 104 throw new Forbidden('No permission to assign tag ' . $tagId); 105 } 106 107 $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); 108 } catch (TagNotFoundException $e) { 109 throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); 110 } 111 } 112 113 public function createDirectory($name) { 114 throw new Forbidden('Permission denied to create collections'); 115 } 116 117 public function getChild($tagName) { 118 try { 119 if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagName, true)) { 120 $tag = $this->tagManager->getTagsByIds([$tagName]); 121 $tag = current($tag); 122 if ($this->tagManager->canUserSeeTag($tag, $this->user)) { 123 return $this->makeNode($tag); 124 } 125 } 126 throw new NotFound('Tag with id ' . $tagName . ' not present for object ' . $this->objectId); 127 } catch (\InvalidArgumentException $e) { 128 throw new BadRequest('Invalid tag id', 0, $e); 129 } catch (TagNotFoundException $e) { 130 throw new NotFound('Tag with id ' . $tagName . ' not found', 0, $e); 131 } 132 } 133 134 public function getChildren() { 135 $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); 136 if (empty($tagIds)) { 137 return []; 138 } 139 $tags = $this->tagManager->getTagsByIds($tagIds); 140 141 // filter out non-visible tags 142 $tags = array_filter($tags, function ($tag) { 143 return $this->tagManager->canUserSeeTag($tag, $this->user); 144 }); 145 146 return array_values(array_map(function ($tag) { 147 return $this->makeNode($tag); 148 }, $tags)); 149 } 150 151 public function childExists($tagId) { 152 try { 153 $result = $this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true); 154 155 if ($result) { 156 $tags = $this->tagManager->getTagsByIds([$tagId]); 157 $tag = current($tags); 158 if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { 159 return false; 160 } 161 } 162 163 return $result; 164 } catch (\InvalidArgumentException $e) { 165 throw new BadRequest('Invalid tag id', 0, $e); 166 } catch (TagNotFoundException $e) { 167 return false; 168 } 169 } 170 171 public function delete() { 172 throw new Forbidden('Permission denied to delete this collection'); 173 } 174 175 public function getName() { 176 return $this->objectId; 177 } 178 179 public function setName($name) { 180 throw new Forbidden('Permission denied to rename this collection'); 181 } 182 183 /** 184 * Returns the last modification time, as a unix timestamp 185 * 186 * @return int 187 */ 188 public function getLastModified() { 189 return null; 190 } 191 192 /** 193 * Create a sabre node for the mapping of the 194 * given system tag to the collection's object 195 * 196 * @param ISystemTag $tag 197 * 198 * @return SystemTagMappingNode 199 */ 200 private function makeNode(ISystemTag $tag) { 201 return new SystemTagMappingNode( 202 $tag, 203 $this->objectId, 204 $this->objectType, 205 $this->user, 206 $this->tagManager, 207 $this->tagMapper 208 ); 209 } 210} 211