| @@ -21,7 +21,6 @@ | ||
| 21 | 21 | namespace OCA\DAV\CardDAV\Xml; | 
| 22 | 22 | |
| 23 | 23 | use Sabre\Xml\XmlSerializable; | 
| 24 | -use Sabre\Xml\Element; | |
| 25 | 24 | use Sabre\Xml\Writer; | 
| 26 | 25 | |
| 27 | 26 |  class Groups implements XmlSerializable { | 
| @@ -26,21 +26,21 @@ | ||
| 26 | 26 | use Sabre\Xml\Writer; | 
| 27 | 27 | |
| 28 | 28 |  class Groups implements XmlSerializable { | 
| 29 | - const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 29 | + const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 30 | 30 | |
| 31 | - /** @var string[] of TYPE:CHECKSUM */ | |
| 32 | - private $groups; | |
| 31 | + /** @var string[] of TYPE:CHECKSUM */ | |
| 32 | + private $groups; | |
| 33 | 33 | |
| 34 | - /** | |
| 35 | - * @param string $groups | |
| 36 | - */ | |
| 37 | -	public function __construct($groups) { | |
| 38 | - $this->groups = $groups; | |
| 39 | - } | |
| 34 | + /** | |
| 35 | + * @param string $groups | |
| 36 | + */ | |
| 37 | +    public function __construct($groups) { | |
| 38 | + $this->groups = $groups; | |
| 39 | + } | |
| 40 | 40 | |
| 41 | -	function xmlSerialize(Writer $writer) { | |
| 42 | -		foreach ($this->groups as $group) { | |
| 43 | -			$writer->writeElement('{' . self::NS_OWNCLOUD . '}group', $group); | |
| 44 | - } | |
| 45 | - } | |
| 41 | +    function xmlSerialize(Writer $writer) { | |
| 42 | +        foreach ($this->groups as $group) { | |
| 43 | +            $writer->writeElement('{' . self::NS_OWNCLOUD . '}group', $group); | |
| 44 | + } | |
| 45 | + } | |
| 46 | 46 | } | 
| @@ -22,11 +22,6 @@ | ||
| 22 | 22 | namespace OCA\DAV\Command; | 
| 23 | 23 | |
| 24 | 24 | use OCA\DAV\CardDAV\CardDavBackend; | 
| 25 | -use OCA\DAV\Connector\Sabre\Principal; | |
| 26 | -use OCP\IConfig; | |
| 27 | -use OCP\IDBConnection; | |
| 28 | -use OCP\IGroupManager; | |
| 29 | -use OCP\ILogger; | |
| 30 | 25 | use OCP\IUserManager; | 
| 31 | 26 | use Symfony\Component\Console\Command\Command; | 
| 32 | 27 | use Symfony\Component\Console\Input\InputArgument; | 
| @@ -36,43 +36,43 @@ | ||
| 36 | 36 | |
| 37 | 37 |  class CreateAddressBook extends Command { | 
| 38 | 38 | |
| 39 | - /** @var IUserManager */ | |
| 40 | - private $userManager; | |
| 39 | + /** @var IUserManager */ | |
| 40 | + private $userManager; | |
| 41 | 41 | |
| 42 | - /** @var CardDavBackend */ | |
| 43 | - private $cardDavBackend; | |
| 42 | + /** @var CardDavBackend */ | |
| 43 | + private $cardDavBackend; | |
| 44 | 44 | |
| 45 | - /** | |
| 46 | - * @param IUserManager $userManager | |
| 47 | - * @param CardDavBackend $cardDavBackend | |
| 48 | - */ | |
| 49 | - function __construct(IUserManager $userManager, | |
| 50 | - CardDavBackend $cardDavBackend | |
| 51 | -	) { | |
| 52 | - parent::__construct(); | |
| 53 | - $this->userManager = $userManager; | |
| 54 | - $this->cardDavBackend = $cardDavBackend; | |
| 55 | - } | |
| 45 | + /** | |
| 46 | + * @param IUserManager $userManager | |
| 47 | + * @param CardDavBackend $cardDavBackend | |
| 48 | + */ | |
| 49 | + function __construct(IUserManager $userManager, | |
| 50 | + CardDavBackend $cardDavBackend | |
| 51 | +    ) { | |
| 52 | + parent::__construct(); | |
| 53 | + $this->userManager = $userManager; | |
| 54 | + $this->cardDavBackend = $cardDavBackend; | |
| 55 | + } | |
| 56 | 56 | |
| 57 | -	protected function configure() { | |
| 58 | - $this | |
| 59 | -				->setName('dav:create-addressbook') | |
| 60 | -				->setDescription('Create a dav addressbook') | |
| 61 | -				->addArgument('user', | |
| 62 | - InputArgument::REQUIRED, | |
| 63 | - 'User for whom the addressbook will be created') | |
| 64 | -				->addArgument('name', | |
| 65 | - InputArgument::REQUIRED, | |
| 66 | - 'Name of the addressbook'); | |
| 67 | - } | |
| 57 | +    protected function configure() { | |
| 58 | + $this | |
| 59 | +                ->setName('dav:create-addressbook') | |
| 60 | +                ->setDescription('Create a dav addressbook') | |
| 61 | +                ->addArgument('user', | |
| 62 | + InputArgument::REQUIRED, | |
| 63 | + 'User for whom the addressbook will be created') | |
| 64 | +                ->addArgument('name', | |
| 65 | + InputArgument::REQUIRED, | |
| 66 | + 'Name of the addressbook'); | |
| 67 | + } | |
| 68 | 68 | |
| 69 | -	protected function execute(InputInterface $input, OutputInterface $output) { | |
| 70 | -		$user = $input->getArgument('user'); | |
| 71 | -		if (!$this->userManager->userExists($user)) { | |
| 72 | -			throw new \InvalidArgumentException("User <$user> in unknown."); | |
| 73 | - } | |
| 69 | +    protected function execute(InputInterface $input, OutputInterface $output) { | |
| 70 | +        $user = $input->getArgument('user'); | |
| 71 | +        if (!$this->userManager->userExists($user)) { | |
| 72 | +            throw new \InvalidArgumentException("User <$user> in unknown."); | |
| 73 | + } | |
| 74 | 74 | |
| 75 | -		$name = $input->getArgument('name'); | |
| 76 | -		$this->cardDavBackend->createAddressBook("principals/users/$user", $name, []); | |
| 77 | - } | |
| 75 | +        $name = $input->getArgument('name'); | |
| 76 | +        $this->cardDavBackend->createAddressBook("principals/users/$user", $name, []); | |
| 77 | + } | |
| 78 | 78 | } | 
| @@ -21,10 +21,8 @@ | ||
| 21 | 21 | namespace OCA\DAV\Command; | 
| 22 | 22 | |
| 23 | 23 | use OCA\DAV\CardDAV\SyncService; | 
| 24 | -use OCP\IUserManager; | |
| 25 | 24 | use Symfony\Component\Console\Command\Command; | 
| 26 | 25 | use Symfony\Component\Console\Helper\ProgressBar; | 
| 27 | -use Symfony\Component\Console\Input\InputArgument; | |
| 28 | 26 | use Symfony\Component\Console\Input\InputInterface; | 
| 29 | 27 | use Symfony\Component\Console\Output\OutputInterface; | 
| 30 | 28 | |
| @@ -31,36 +31,36 @@ | ||
| 31 | 31 | |
| 32 | 32 |  class SyncSystemAddressBook extends Command { | 
| 33 | 33 | |
| 34 | - /** @var SyncService */ | |
| 35 | - private $syncService; | |
| 34 | + /** @var SyncService */ | |
| 35 | + private $syncService; | |
| 36 | 36 | |
| 37 | - /** | |
| 38 | - * @param SyncService $syncService | |
| 39 | - */ | |
| 40 | -	function __construct(SyncService $syncService) { | |
| 41 | - parent::__construct(); | |
| 42 | - $this->syncService = $syncService; | |
| 43 | - } | |
| 37 | + /** | |
| 38 | + * @param SyncService $syncService | |
| 39 | + */ | |
| 40 | +    function __construct(SyncService $syncService) { | |
| 41 | + parent::__construct(); | |
| 42 | + $this->syncService = $syncService; | |
| 43 | + } | |
| 44 | 44 | |
| 45 | -	protected function configure() { | |
| 46 | - $this | |
| 47 | -			->setName('dav:sync-system-addressbook') | |
| 48 | -			->setDescription('Synchronizes users to the system addressbook'); | |
| 49 | - } | |
| 45 | +    protected function configure() { | |
| 46 | + $this | |
| 47 | +            ->setName('dav:sync-system-addressbook') | |
| 48 | +            ->setDescription('Synchronizes users to the system addressbook'); | |
| 49 | + } | |
| 50 | 50 | |
| 51 | - /** | |
| 52 | - * @param InputInterface $input | |
| 53 | - * @param OutputInterface $output | |
| 54 | - */ | |
| 55 | -	protected function execute(InputInterface $input, OutputInterface $output) { | |
| 56 | -		$output->writeln('Syncing users ...'); | |
| 57 | - $progress = new ProgressBar($output); | |
| 58 | - $progress->start(); | |
| 59 | -		$this->syncService->syncInstance(function() use ($progress) { | |
| 60 | - $progress->advance(); | |
| 61 | - }); | |
| 51 | + /** | |
| 52 | + * @param InputInterface $input | |
| 53 | + * @param OutputInterface $output | |
| 54 | + */ | |
| 55 | +    protected function execute(InputInterface $input, OutputInterface $output) { | |
| 56 | +        $output->writeln('Syncing users ...'); | |
| 57 | + $progress = new ProgressBar($output); | |
| 58 | + $progress->start(); | |
| 59 | +        $this->syncService->syncInstance(function() use ($progress) { | |
| 60 | + $progress->advance(); | |
| 61 | + }); | |
| 62 | 62 | |
| 63 | - $progress->finish(); | |
| 64 | -		$output->writeln(''); | |
| 65 | - } | |
| 63 | + $progress->finish(); | |
| 64 | +        $output->writeln(''); | |
| 65 | + } | |
| 66 | 66 | } | 
| @@ -21,7 +21,6 @@ | ||
| 21 | 21 | namespace OCA\DAV\Connector\Sabre; | 
| 22 | 22 | |
| 23 | 23 | use Sabre\Xml\XmlSerializable; | 
| 24 | -use Sabre\Xml\Element; | |
| 25 | 24 | use Sabre\Xml\Writer; | 
| 26 | 25 | |
| 27 | 26 | /** | 
| @@ -32,41 +32,41 @@ | ||
| 32 | 32 | * checksum name. | 
| 33 | 33 | */ | 
| 34 | 34 |  class ChecksumList implements XmlSerializable { | 
| 35 | - const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 35 | + const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 36 | 36 | |
| 37 | - /** @var string[] of TYPE:CHECKSUM */ | |
| 38 | - private $checksums; | |
| 37 | + /** @var string[] of TYPE:CHECKSUM */ | |
| 38 | + private $checksums; | |
| 39 | 39 | |
| 40 | - /** | |
| 41 | - * @param string $checksum | |
| 42 | - */ | |
| 43 | -	public function __construct($checksum) { | |
| 44 | -		$this->checksums = explode(',', $checksum); | |
| 45 | - } | |
| 40 | + /** | |
| 41 | + * @param string $checksum | |
| 42 | + */ | |
| 43 | +    public function __construct($checksum) { | |
| 44 | +        $this->checksums = explode(',', $checksum); | |
| 45 | + } | |
| 46 | 46 | |
| 47 | - /** | |
| 48 | - * The xmlSerialize metod is called during xml writing. | |
| 49 | - * | |
| 50 | - * Use the $writer argument to write its own xml serialization. | |
| 51 | - * | |
| 52 | - * An important note: do _not_ create a parent element. Any element | |
| 53 | - * implementing XmlSerializble should only ever write what's considered | |
| 54 | - * its 'inner xml'. | |
| 55 | - * | |
| 56 | - * The parent of the current element is responsible for writing a | |
| 57 | - * containing element. | |
| 58 | - * | |
| 59 | - * This allows serializers to be re-used for different element names. | |
| 60 | - * | |
| 61 | - * If you are opening new elements, you must also close them again. | |
| 62 | - * | |
| 63 | - * @param Writer $writer | |
| 64 | - * @return void | |
| 65 | - */ | |
| 66 | -	function xmlSerialize(Writer $writer) { | |
| 47 | + /** | |
| 48 | + * The xmlSerialize metod is called during xml writing. | |
| 49 | + * | |
| 50 | + * Use the $writer argument to write its own xml serialization. | |
| 51 | + * | |
| 52 | + * An important note: do _not_ create a parent element. Any element | |
| 53 | + * implementing XmlSerializble should only ever write what's considered | |
| 54 | + * its 'inner xml'. | |
| 55 | + * | |
| 56 | + * The parent of the current element is responsible for writing a | |
| 57 | + * containing element. | |
| 58 | + * | |
| 59 | + * This allows serializers to be re-used for different element names. | |
| 60 | + * | |
| 61 | + * If you are opening new elements, you must also close them again. | |
| 62 | + * | |
| 63 | + * @param Writer $writer | |
| 64 | + * @return void | |
| 65 | + */ | |
| 66 | +    function xmlSerialize(Writer $writer) { | |
| 67 | 67 | |
| 68 | -		foreach ($this->checksums as $checksum) { | |
| 69 | -			$writer->writeElement('{' . self::NS_OWNCLOUD . '}checksum', $checksum); | |
| 70 | - } | |
| 71 | - } | |
| 68 | +        foreach ($this->checksums as $checksum) { | |
| 69 | +            $writer->writeElement('{' . self::NS_OWNCLOUD . '}checksum', $checksum); | |
| 70 | + } | |
| 71 | + } | |
| 72 | 72 | } | 
| @@ -24,7 +24,6 @@ | ||
| 24 | 24 | use OCA\DAV\Connector\Sabre\Auth; | 
| 25 | 25 | use OCA\DAV\DAV\Sharing\Xml\Invite; | 
| 26 | 26 | use OCP\IRequest; | 
| 27 | -use Sabre\DAV\Exception\BadRequest; | |
| 28 | 27 | use Sabre\DAV\Exception\NotFound; | 
| 29 | 28 | use Sabre\DAV\INode; | 
| 30 | 29 | use Sabre\DAV\PropFind; | 
| @@ -36,166 +36,166 @@ | ||
| 36 | 36 | |
| 37 | 37 |  class Plugin extends ServerPlugin { | 
| 38 | 38 | |
| 39 | - const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 40 | - | |
| 41 | - /** @var Auth */ | |
| 42 | - private $auth; | |
| 43 | - | |
| 44 | - /** @var IRequest */ | |
| 45 | - private $request; | |
| 46 | - | |
| 47 | - /** | |
| 48 | - * Plugin constructor. | |
| 49 | - * | |
| 50 | - * @param Auth $authBackEnd | |
| 51 | - * @param IRequest $request | |
| 52 | - */ | |
| 53 | -	public function __construct(Auth $authBackEnd, IRequest $request) { | |
| 54 | - $this->auth = $authBackEnd; | |
| 55 | - $this->request = $request; | |
| 56 | - } | |
| 57 | - | |
| 58 | - /** | |
| 59 | - * Reference to SabreDAV server object. | |
| 60 | - * | |
| 61 | - * @var \Sabre\DAV\Server | |
| 62 | - */ | |
| 63 | - protected $server; | |
| 64 | - | |
| 65 | - /** | |
| 66 | - * This method should return a list of server-features. | |
| 67 | - * | |
| 68 | - * This is for example 'versioning' and is added to the DAV: header | |
| 69 | - * in an OPTIONS response. | |
| 70 | - * | |
| 71 | - * @return string[] | |
| 72 | - */ | |
| 73 | -	function getFeatures() { | |
| 74 | - return ['oc-resource-sharing']; | |
| 75 | - } | |
| 76 | - | |
| 77 | - /** | |
| 78 | - * Returns a plugin name. | |
| 79 | - * | |
| 80 | - * Using this name other plugins will be able to access other plugins | |
| 81 | - * using Sabre\DAV\Server::getPlugin | |
| 82 | - * | |
| 83 | - * @return string | |
| 84 | - */ | |
| 85 | -	function getPluginName() { | |
| 86 | - return 'oc-resource-sharing'; | |
| 87 | - } | |
| 88 | - | |
| 89 | - /** | |
| 90 | - * This initializes the plugin. | |
| 91 | - * | |
| 92 | - * This function is called by Sabre\DAV\Server, after | |
| 93 | - * addPlugin is called. | |
| 94 | - * | |
| 95 | - * This method should set up the required event subscriptions. | |
| 96 | - * | |
| 97 | - * @param Server $server | |
| 98 | - * @return void | |
| 99 | - */ | |
| 100 | -	function initialize(Server $server) { | |
| 101 | - $this->server = $server; | |
| 102 | -		$this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = 'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest'; | |
| 103 | -		$this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}invite'] = 'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite'; | |
| 104 | - | |
| 105 | -		$this->server->on('method:POST', [$this, 'httpPost']); | |
| 106 | -		$this->server->on('propFind',    [$this, 'propFind']); | |
| 107 | - } | |
| 108 | - | |
| 109 | - /** | |
| 110 | - * We intercept this to handle POST requests on a dav resource. | |
| 111 | - * | |
| 112 | - * @param RequestInterface $request | |
| 113 | - * @param ResponseInterface $response | |
| 114 | - * @return null|false | |
| 115 | - */ | |
| 116 | -	function httpPost(RequestInterface $request, ResponseInterface $response) { | |
| 117 | - | |
| 118 | - $path = $request->getPath(); | |
| 119 | - | |
| 120 | - // Only handling xml | |
| 121 | -		$contentType = $request->getHeader('Content-Type'); | |
| 122 | - if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) | |
| 123 | - return; | |
| 124 | - | |
| 125 | - // Making sure the node exists | |
| 126 | -		try { | |
| 127 | - $node = $this->server->tree->getNodeForPath($path); | |
| 128 | -		} catch (NotFound $e) { | |
| 129 | - return; | |
| 130 | - } | |
| 131 | - | |
| 132 | - $requestBody = $request->getBodyAsString(); | |
| 133 | - | |
| 134 | - // If this request handler could not deal with this POST request, it | |
| 135 | - // will return 'null' and other plugins get a chance to handle the | |
| 136 | - // request. | |
| 137 | - // | |
| 138 | - // However, we already requested the full body. This is a problem, | |
| 139 | - // because a body can only be read once. This is why we preemptively | |
| 140 | - // re-populated the request body with the existing data. | |
| 141 | - $request->setBody($requestBody); | |
| 142 | - | |
| 143 | - $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); | |
| 144 | - | |
| 145 | -		switch ($documentType) { | |
| 146 | - | |
| 147 | - // Dealing with the 'share' document, which modified invitees on a | |
| 148 | - // calendar. | |
| 149 | -			case '{' . self::NS_OWNCLOUD . '}share' : | |
| 150 | - | |
| 151 | - // We can only deal with IShareableCalendar objects | |
| 152 | -				if (!$node instanceof IShareable) { | |
| 153 | - return; | |
| 154 | - } | |
| 155 | - | |
| 156 | - $this->server->transactionType = 'post-oc-resource-share'; | |
| 157 | - | |
| 158 | - // Getting ACL info | |
| 159 | -				$acl = $this->server->getPlugin('acl'); | |
| 160 | - | |
| 161 | - // If there's no ACL support, we allow everything | |
| 162 | -				if ($acl) { | |
| 163 | - /** @var \Sabre\DAVACL\Plugin $acl */ | |
| 164 | -					$acl->checkPrivileges($path, '{DAV:}write'); | |
| 165 | - } | |
| 166 | - | |
| 167 | - $node->updateShares($message->set, $message->remove); | |
| 168 | - | |
| 169 | - $response->setStatus(200); | |
| 170 | - // Adding this because sending a response body may cause issues, | |
| 171 | - // and I wanted some type of indicator the response was handled. | |
| 172 | -				$response->setHeader('X-Sabre-Status', 'everything-went-well'); | |
| 173 | - | |
| 174 | - // Breaking the event chain | |
| 175 | - return false; | |
| 176 | - } | |
| 177 | - } | |
| 178 | - | |
| 179 | - /** | |
| 180 | - * This event is triggered when properties are requested for a certain | |
| 181 | - * node. | |
| 182 | - * | |
| 183 | - * This allows us to inject any properties early. | |
| 184 | - * | |
| 185 | - * @param PropFind $propFind | |
| 186 | - * @param INode $node | |
| 187 | - * @return void | |
| 188 | - */ | |
| 189 | -	function propFind(PropFind $propFind, INode $node) { | |
| 190 | -		if ($node instanceof IShareable) { | |
| 191 | - | |
| 192 | -			$propFind->handle('{' . Plugin::NS_OWNCLOUD . '}invite', function() use ($node) { | |
| 193 | - return new Invite( | |
| 194 | - $node->getShares() | |
| 195 | - ); | |
| 196 | - }); | |
| 197 | - | |
| 198 | - } | |
| 199 | - } | |
| 39 | + const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 40 | + | |
| 41 | + /** @var Auth */ | |
| 42 | + private $auth; | |
| 43 | + | |
| 44 | + /** @var IRequest */ | |
| 45 | + private $request; | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Plugin constructor. | |
| 49 | + * | |
| 50 | + * @param Auth $authBackEnd | |
| 51 | + * @param IRequest $request | |
| 52 | + */ | |
| 53 | +    public function __construct(Auth $authBackEnd, IRequest $request) { | |
| 54 | + $this->auth = $authBackEnd; | |
| 55 | + $this->request = $request; | |
| 56 | + } | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Reference to SabreDAV server object. | |
| 60 | + * | |
| 61 | + * @var \Sabre\DAV\Server | |
| 62 | + */ | |
| 63 | + protected $server; | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * This method should return a list of server-features. | |
| 67 | + * | |
| 68 | + * This is for example 'versioning' and is added to the DAV: header | |
| 69 | + * in an OPTIONS response. | |
| 70 | + * | |
| 71 | + * @return string[] | |
| 72 | + */ | |
| 73 | +    function getFeatures() { | |
| 74 | + return ['oc-resource-sharing']; | |
| 75 | + } | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * Returns a plugin name. | |
| 79 | + * | |
| 80 | + * Using this name other plugins will be able to access other plugins | |
| 81 | + * using Sabre\DAV\Server::getPlugin | |
| 82 | + * | |
| 83 | + * @return string | |
| 84 | + */ | |
| 85 | +    function getPluginName() { | |
| 86 | + return 'oc-resource-sharing'; | |
| 87 | + } | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * This initializes the plugin. | |
| 91 | + * | |
| 92 | + * This function is called by Sabre\DAV\Server, after | |
| 93 | + * addPlugin is called. | |
| 94 | + * | |
| 95 | + * This method should set up the required event subscriptions. | |
| 96 | + * | |
| 97 | + * @param Server $server | |
| 98 | + * @return void | |
| 99 | + */ | |
| 100 | +    function initialize(Server $server) { | |
| 101 | + $this->server = $server; | |
| 102 | +        $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = 'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest'; | |
| 103 | +        $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}invite'] = 'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite'; | |
| 104 | + | |
| 105 | +        $this->server->on('method:POST', [$this, 'httpPost']); | |
| 106 | +        $this->server->on('propFind',    [$this, 'propFind']); | |
| 107 | + } | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * We intercept this to handle POST requests on a dav resource. | |
| 111 | + * | |
| 112 | + * @param RequestInterface $request | |
| 113 | + * @param ResponseInterface $response | |
| 114 | + * @return null|false | |
| 115 | + */ | |
| 116 | +    function httpPost(RequestInterface $request, ResponseInterface $response) { | |
| 117 | + | |
| 118 | + $path = $request->getPath(); | |
| 119 | + | |
| 120 | + // Only handling xml | |
| 121 | +        $contentType = $request->getHeader('Content-Type'); | |
| 122 | + if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) | |
| 123 | + return; | |
| 124 | + | |
| 125 | + // Making sure the node exists | |
| 126 | +        try { | |
| 127 | + $node = $this->server->tree->getNodeForPath($path); | |
| 128 | +        } catch (NotFound $e) { | |
| 129 | + return; | |
| 130 | + } | |
| 131 | + | |
| 132 | + $requestBody = $request->getBodyAsString(); | |
| 133 | + | |
| 134 | + // If this request handler could not deal with this POST request, it | |
| 135 | + // will return 'null' and other plugins get a chance to handle the | |
| 136 | + // request. | |
| 137 | + // | |
| 138 | + // However, we already requested the full body. This is a problem, | |
| 139 | + // because a body can only be read once. This is why we preemptively | |
| 140 | + // re-populated the request body with the existing data. | |
| 141 | + $request->setBody($requestBody); | |
| 142 | + | |
| 143 | + $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); | |
| 144 | + | |
| 145 | +        switch ($documentType) { | |
| 146 | + | |
| 147 | + // Dealing with the 'share' document, which modified invitees on a | |
| 148 | + // calendar. | |
| 149 | +            case '{' . self::NS_OWNCLOUD . '}share' : | |
| 150 | + | |
| 151 | + // We can only deal with IShareableCalendar objects | |
| 152 | +                if (!$node instanceof IShareable) { | |
| 153 | + return; | |
| 154 | + } | |
| 155 | + | |
| 156 | + $this->server->transactionType = 'post-oc-resource-share'; | |
| 157 | + | |
| 158 | + // Getting ACL info | |
| 159 | +                $acl = $this->server->getPlugin('acl'); | |
| 160 | + | |
| 161 | + // If there's no ACL support, we allow everything | |
| 162 | +                if ($acl) { | |
| 163 | + /** @var \Sabre\DAVACL\Plugin $acl */ | |
| 164 | +                    $acl->checkPrivileges($path, '{DAV:}write'); | |
| 165 | + } | |
| 166 | + | |
| 167 | + $node->updateShares($message->set, $message->remove); | |
| 168 | + | |
| 169 | + $response->setStatus(200); | |
| 170 | + // Adding this because sending a response body may cause issues, | |
| 171 | + // and I wanted some type of indicator the response was handled. | |
| 172 | +                $response->setHeader('X-Sabre-Status', 'everything-went-well'); | |
| 173 | + | |
| 174 | + // Breaking the event chain | |
| 175 | + return false; | |
| 176 | + } | |
| 177 | + } | |
| 178 | + | |
| 179 | + /** | |
| 180 | + * This event is triggered when properties are requested for a certain | |
| 181 | + * node. | |
| 182 | + * | |
| 183 | + * This allows us to inject any properties early. | |
| 184 | + * | |
| 185 | + * @param PropFind $propFind | |
| 186 | + * @param INode $node | |
| 187 | + * @return void | |
| 188 | + */ | |
| 189 | +    function propFind(PropFind $propFind, INode $node) { | |
| 190 | +        if ($node instanceof IShareable) { | |
| 191 | + | |
| 192 | +            $propFind->handle('{' . Plugin::NS_OWNCLOUD . '}invite', function() use ($node) { | |
| 193 | + return new Invite( | |
| 194 | + $node->getShares() | |
| 195 | + ); | |
| 196 | + }); | |
| 197 | + | |
| 198 | + } | |
| 199 | + } | |
| 200 | 200 | |
| 201 | 201 | } | 
| @@ -29,9 +29,7 @@ | ||
| 29 | 29 | use Sabre\DAV\Exception\BadRequest; | 
| 30 | 30 | use Sabre\DAV\Exception\Conflict; | 
| 31 | 31 | use Sabre\DAV\Exception\Forbidden; | 
| 32 | -use Sabre\DAV\Exception\NotFound; | |
| 33 | 32 | use Sabre\DAV\Exception\UnsupportedMediaType; | 
| 34 | - | |
| 35 | 33 | use OCP\SystemTag\ISystemTag; | 
| 36 | 34 | use OCP\SystemTag\ISystemTagManager; | 
| 37 | 35 | use OCP\SystemTag\TagAlreadyExistsException; | 
| @@ -49,280 +49,280 @@ | ||
| 49 | 49 | */ | 
| 50 | 50 |  class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { | 
| 51 | 51 | |
| 52 | - // namespace | |
| 53 | - const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 54 | -	const ID_PROPERTYNAME = '{http://owncloud.org/ns}id'; | |
| 55 | -	const DISPLAYNAME_PROPERTYNAME = '{http://owncloud.org/ns}display-name'; | |
| 56 | -	const USERVISIBLE_PROPERTYNAME = '{http://owncloud.org/ns}user-visible'; | |
| 57 | -	const USERASSIGNABLE_PROPERTYNAME = '{http://owncloud.org/ns}user-assignable'; | |
| 58 | -	const GROUPS_PROPERTYNAME = '{http://owncloud.org/ns}groups'; | |
| 59 | -	const CANASSIGN_PROPERTYNAME = '{http://owncloud.org/ns}can-assign'; | |
| 60 | - | |
| 61 | - /** | |
| 62 | - * @var \Sabre\DAV\Server $server | |
| 63 | - */ | |
| 64 | - private $server; | |
| 65 | - | |
| 66 | - /** | |
| 67 | - * @var ISystemTagManager | |
| 68 | - */ | |
| 69 | - protected $tagManager; | |
| 70 | - | |
| 71 | - /** | |
| 72 | - * @var IUserSession | |
| 73 | - */ | |
| 74 | - protected $userSession; | |
| 75 | - | |
| 76 | - /** | |
| 77 | - * @var IGroupManager | |
| 78 | - */ | |
| 79 | - protected $groupManager; | |
| 80 | - | |
| 81 | - /** | |
| 82 | - * @param ISystemTagManager $tagManager tag manager | |
| 83 | - * @param IGroupManager $groupManager | |
| 84 | - * @param IUserSession $userSession | |
| 85 | - */ | |
| 86 | - public function __construct(ISystemTagManager $tagManager, | |
| 87 | - IGroupManager $groupManager, | |
| 88 | -								IUserSession $userSession) { | |
| 89 | - $this->tagManager = $tagManager; | |
| 90 | - $this->userSession = $userSession; | |
| 91 | - $this->groupManager = $groupManager; | |
| 92 | - } | |
| 93 | - | |
| 94 | - /** | |
| 95 | - * This initializes the plugin. | |
| 96 | - * | |
| 97 | - * This function is called by \Sabre\DAV\Server, after | |
| 98 | - * addPlugin is called. | |
| 99 | - * | |
| 100 | - * This method should set up the required event subscriptions. | |
| 101 | - * | |
| 102 | - * @param \Sabre\DAV\Server $server | |
| 103 | - * @return void | |
| 104 | - */ | |
| 105 | -	public function initialize(\Sabre\DAV\Server $server) { | |
| 106 | - | |
| 107 | - $server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc'; | |
| 108 | - | |
| 109 | - $server->protectedProperties[] = self::ID_PROPERTYNAME; | |
| 110 | - | |
| 111 | -		$server->on('propFind', array($this, 'handleGetProperties')); | |
| 112 | -		$server->on('propPatch', array($this, 'handleUpdateProperties')); | |
| 113 | -		$server->on('method:POST', [$this, 'httpPost']); | |
| 114 | - | |
| 115 | - $this->server = $server; | |
| 116 | - } | |
| 117 | - | |
| 118 | - /** | |
| 119 | - * POST operation on system tag collections | |
| 120 | - * | |
| 121 | - * @param RequestInterface $request request object | |
| 122 | - * @param ResponseInterface $response response object | |
| 123 | - * @return null|false | |
| 124 | - */ | |
| 125 | -	public function httpPost(RequestInterface $request, ResponseInterface $response) { | |
| 126 | - $path = $request->getPath(); | |
| 127 | - | |
| 128 | - // Making sure the node exists | |
| 129 | - $node = $this->server->tree->getNodeForPath($path); | |
| 130 | -		if ($node instanceof SystemTagsByIdCollection || $node instanceof SystemTagsObjectMappingCollection) { | |
| 131 | - $data = $request->getBodyAsString(); | |
| 132 | - | |
| 133 | -			$tag = $this->createTag($data, $request->getHeader('Content-Type')); | |
| 134 | - | |
| 135 | -			if ($node instanceof SystemTagsObjectMappingCollection) { | |
| 136 | - // also add to collection | |
| 137 | - $node->createFile($tag->getId()); | |
| 138 | - $url = $request->getBaseUrl() . 'systemtags/'; | |
| 139 | -			} else { | |
| 140 | - $url = $request->getUrl(); | |
| 141 | - } | |
| 142 | - | |
| 143 | -			if ($url[strlen($url) - 1] !== '/') { | |
| 144 | - $url .= '/'; | |
| 145 | - } | |
| 146 | - | |
| 147 | -			$response->setHeader('Content-Location', $url . $tag->getId()); | |
| 148 | - | |
| 149 | - // created | |
| 150 | - $response->setStatus(201); | |
| 151 | - return false; | |
| 152 | - } | |
| 153 | - } | |
| 154 | - | |
| 155 | - /** | |
| 156 | - * Creates a new tag | |
| 157 | - * | |
| 158 | - * @param string $data JSON encoded string containing the properties of the tag to create | |
| 159 | - * @param string $contentType content type of the data | |
| 160 | - * @return ISystemTag newly created system tag | |
| 161 | - * | |
| 162 | - * @throws BadRequest if a field was missing | |
| 163 | - * @throws Conflict if a tag with the same properties already exists | |
| 164 | - * @throws UnsupportedMediaType if the content type is not supported | |
| 165 | - */ | |
| 166 | -	private function createTag($data, $contentType = 'application/json') { | |
| 167 | -		if (explode(';', $contentType)[0] === 'application/json') { | |
| 168 | - $data = json_decode($data, true); | |
| 169 | -		} else { | |
| 170 | - throw new UnsupportedMediaType(); | |
| 171 | - } | |
| 172 | - | |
| 173 | -		if (!isset($data['name'])) { | |
| 174 | -			throw new BadRequest('Missing "name" attribute'); | |
| 175 | - } | |
| 176 | - | |
| 177 | - $tagName = $data['name']; | |
| 178 | - $userVisible = true; | |
| 179 | - $userAssignable = true; | |
| 180 | - | |
| 181 | -		if (isset($data['userVisible'])) { | |
| 182 | - $userVisible = (bool)$data['userVisible']; | |
| 183 | - } | |
| 184 | - | |
| 185 | -		if (isset($data['userAssignable'])) { | |
| 186 | - $userAssignable = (bool)$data['userAssignable']; | |
| 187 | - } | |
| 188 | - | |
| 189 | - $groups = []; | |
| 190 | -		if (isset($data['groups'])) { | |
| 191 | - $groups = $data['groups']; | |
| 192 | -			if (is_string($groups)) { | |
| 193 | -				$groups = explode('|', $groups); | |
| 194 | - } | |
| 195 | - } | |
| 196 | - | |
| 197 | -		if($userVisible === false || $userAssignable === false || !empty($groups)) { | |
| 198 | -			if(!$this->userSession->isLoggedIn() || !$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 199 | -				throw new BadRequest('Not sufficient permissions'); | |
| 200 | - } | |
| 201 | - } | |
| 202 | - | |
| 203 | -		try { | |
| 204 | - $tag = $this->tagManager->createTag($tagName, $userVisible, $userAssignable); | |
| 205 | -			if (!empty($groups)) { | |
| 206 | - $this->tagManager->setTagGroups($tag, $groups); | |
| 207 | - } | |
| 208 | - return $tag; | |
| 209 | -		} catch (TagAlreadyExistsException $e) { | |
| 210 | -			throw new Conflict('Tag already exists', 0, $e); | |
| 211 | - } | |
| 212 | - } | |
| 213 | - | |
| 214 | - | |
| 215 | - /** | |
| 216 | - * Retrieves system tag properties | |
| 217 | - * | |
| 218 | - * @param PropFind $propFind | |
| 219 | - * @param \Sabre\DAV\INode $node | |
| 220 | - */ | |
| 221 | - public function handleGetProperties( | |
| 222 | - PropFind $propFind, | |
| 223 | - \Sabre\DAV\INode $node | |
| 224 | -	) { | |
| 225 | -		if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagMappingNode)) { | |
| 226 | - return; | |
| 227 | - } | |
| 228 | - | |
| 229 | -		$propFind->handle(self::ID_PROPERTYNAME, function() use ($node) { | |
| 230 | - return $node->getSystemTag()->getId(); | |
| 231 | - }); | |
| 232 | - | |
| 233 | -		$propFind->handle(self::DISPLAYNAME_PROPERTYNAME, function() use ($node) { | |
| 234 | - return $node->getSystemTag()->getName(); | |
| 235 | - }); | |
| 236 | - | |
| 237 | -		$propFind->handle(self::USERVISIBLE_PROPERTYNAME, function() use ($node) { | |
| 238 | - return $node->getSystemTag()->isUserVisible() ? 'true' : 'false'; | |
| 239 | - }); | |
| 240 | - | |
| 241 | -		$propFind->handle(self::USERASSIGNABLE_PROPERTYNAME, function() use ($node) { | |
| 242 | - // this is the tag's inherent property "is user assignable" | |
| 243 | - return $node->getSystemTag()->isUserAssignable() ? 'true' : 'false'; | |
| 244 | - }); | |
| 245 | - | |
| 246 | -		$propFind->handle(self::CANASSIGN_PROPERTYNAME, function() use ($node) { | |
| 247 | - // this is the effective permission for the current user | |
| 248 | - return $this->tagManager->canUserAssignTag($node->getSystemTag(), $this->userSession->getUser()) ? 'true' : 'false'; | |
| 249 | - }); | |
| 250 | - | |
| 251 | -		$propFind->handle(self::GROUPS_PROPERTYNAME, function() use ($node) { | |
| 252 | -			if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 253 | - // property only available for admins | |
| 254 | - throw new Forbidden(); | |
| 255 | - } | |
| 256 | - $groups = []; | |
| 257 | - // no need to retrieve groups for namespaces that don't qualify | |
| 258 | -			if ($node->getSystemTag()->isUserVisible() && !$node->getSystemTag()->isUserAssignable()) { | |
| 259 | - $groups = $this->tagManager->getTagGroups($node->getSystemTag()); | |
| 260 | - } | |
| 261 | -			return implode('|', $groups); | |
| 262 | - }); | |
| 263 | - } | |
| 264 | - | |
| 265 | - /** | |
| 266 | - * Updates tag attributes | |
| 267 | - * | |
| 268 | - * @param string $path | |
| 269 | - * @param PropPatch $propPatch | |
| 270 | - * | |
| 271 | - * @return void | |
| 272 | - */ | |
| 273 | -	public function handleUpdateProperties($path, PropPatch $propPatch) { | |
| 274 | - $propPatch->handle([ | |
| 275 | - self::DISPLAYNAME_PROPERTYNAME, | |
| 276 | - self::USERVISIBLE_PROPERTYNAME, | |
| 277 | - self::USERASSIGNABLE_PROPERTYNAME, | |
| 278 | - self::GROUPS_PROPERTYNAME, | |
| 279 | -		], function($props) use ($path) { | |
| 280 | - $node = $this->server->tree->getNodeForPath($path); | |
| 281 | -			if (!($node instanceof SystemTagNode)) { | |
| 282 | - return; | |
| 283 | - } | |
| 284 | - | |
| 285 | - $tag = $node->getSystemTag(); | |
| 286 | - $name = $tag->getName(); | |
| 287 | - $userVisible = $tag->isUserVisible(); | |
| 288 | - $userAssignable = $tag->isUserAssignable(); | |
| 289 | - | |
| 290 | - $updateTag = false; | |
| 291 | - | |
| 292 | -			if (isset($props[self::DISPLAYNAME_PROPERTYNAME])) { | |
| 293 | - $name = $props[self::DISPLAYNAME_PROPERTYNAME]; | |
| 294 | - $updateTag = true; | |
| 295 | - } | |
| 296 | - | |
| 297 | -			if (isset($props[self::USERVISIBLE_PROPERTYNAME])) { | |
| 298 | - $propValue = $props[self::USERVISIBLE_PROPERTYNAME]; | |
| 299 | - $userVisible = ($propValue !== 'false' && $propValue !== '0'); | |
| 300 | - $updateTag = true; | |
| 301 | - } | |
| 302 | - | |
| 303 | -			if (isset($props[self::USERASSIGNABLE_PROPERTYNAME])) { | |
| 304 | - $propValue = $props[self::USERASSIGNABLE_PROPERTYNAME]; | |
| 305 | - $userAssignable = ($propValue !== 'false' && $propValue !== '0'); | |
| 306 | - $updateTag = true; | |
| 307 | - } | |
| 308 | - | |
| 309 | -			if (isset($props[self::GROUPS_PROPERTYNAME])) { | |
| 310 | -				if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 311 | - // property only available for admins | |
| 312 | - throw new Forbidden(); | |
| 313 | - } | |
| 314 | - | |
| 315 | - $propValue = $props[self::GROUPS_PROPERTYNAME]; | |
| 316 | -				$groupIds = explode('|', $propValue); | |
| 317 | - $this->tagManager->setTagGroups($tag, $groupIds); | |
| 318 | - } | |
| 319 | - | |
| 320 | -			if ($updateTag) { | |
| 321 | - $node->update($name, $userVisible, $userAssignable); | |
| 322 | - } | |
| 323 | - | |
| 324 | - return true; | |
| 325 | - }); | |
| 326 | - | |
| 327 | - } | |
| 52 | + // namespace | |
| 53 | + const NS_OWNCLOUD = 'http://owncloud.org/ns'; | |
| 54 | +    const ID_PROPERTYNAME = '{http://owncloud.org/ns}id'; | |
| 55 | +    const DISPLAYNAME_PROPERTYNAME = '{http://owncloud.org/ns}display-name'; | |
| 56 | +    const USERVISIBLE_PROPERTYNAME = '{http://owncloud.org/ns}user-visible'; | |
| 57 | +    const USERASSIGNABLE_PROPERTYNAME = '{http://owncloud.org/ns}user-assignable'; | |
| 58 | +    const GROUPS_PROPERTYNAME = '{http://owncloud.org/ns}groups'; | |
| 59 | +    const CANASSIGN_PROPERTYNAME = '{http://owncloud.org/ns}can-assign'; | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * @var \Sabre\DAV\Server $server | |
| 63 | + */ | |
| 64 | + private $server; | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * @var ISystemTagManager | |
| 68 | + */ | |
| 69 | + protected $tagManager; | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * @var IUserSession | |
| 73 | + */ | |
| 74 | + protected $userSession; | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * @var IGroupManager | |
| 78 | + */ | |
| 79 | + protected $groupManager; | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * @param ISystemTagManager $tagManager tag manager | |
| 83 | + * @param IGroupManager $groupManager | |
| 84 | + * @param IUserSession $userSession | |
| 85 | + */ | |
| 86 | + public function __construct(ISystemTagManager $tagManager, | |
| 87 | + IGroupManager $groupManager, | |
| 88 | +                                IUserSession $userSession) { | |
| 89 | + $this->tagManager = $tagManager; | |
| 90 | + $this->userSession = $userSession; | |
| 91 | + $this->groupManager = $groupManager; | |
| 92 | + } | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * This initializes the plugin. | |
| 96 | + * | |
| 97 | + * This function is called by \Sabre\DAV\Server, after | |
| 98 | + * addPlugin is called. | |
| 99 | + * | |
| 100 | + * This method should set up the required event subscriptions. | |
| 101 | + * | |
| 102 | + * @param \Sabre\DAV\Server $server | |
| 103 | + * @return void | |
| 104 | + */ | |
| 105 | +    public function initialize(\Sabre\DAV\Server $server) { | |
| 106 | + | |
| 107 | + $server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc'; | |
| 108 | + | |
| 109 | + $server->protectedProperties[] = self::ID_PROPERTYNAME; | |
| 110 | + | |
| 111 | +        $server->on('propFind', array($this, 'handleGetProperties')); | |
| 112 | +        $server->on('propPatch', array($this, 'handleUpdateProperties')); | |
| 113 | +        $server->on('method:POST', [$this, 'httpPost']); | |
| 114 | + | |
| 115 | + $this->server = $server; | |
| 116 | + } | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * POST operation on system tag collections | |
| 120 | + * | |
| 121 | + * @param RequestInterface $request request object | |
| 122 | + * @param ResponseInterface $response response object | |
| 123 | + * @return null|false | |
| 124 | + */ | |
| 125 | +    public function httpPost(RequestInterface $request, ResponseInterface $response) { | |
| 126 | + $path = $request->getPath(); | |
| 127 | + | |
| 128 | + // Making sure the node exists | |
| 129 | + $node = $this->server->tree->getNodeForPath($path); | |
| 130 | +        if ($node instanceof SystemTagsByIdCollection || $node instanceof SystemTagsObjectMappingCollection) { | |
| 131 | + $data = $request->getBodyAsString(); | |
| 132 | + | |
| 133 | +            $tag = $this->createTag($data, $request->getHeader('Content-Type')); | |
| 134 | + | |
| 135 | +            if ($node instanceof SystemTagsObjectMappingCollection) { | |
| 136 | + // also add to collection | |
| 137 | + $node->createFile($tag->getId()); | |
| 138 | + $url = $request->getBaseUrl() . 'systemtags/'; | |
| 139 | +            } else { | |
| 140 | + $url = $request->getUrl(); | |
| 141 | + } | |
| 142 | + | |
| 143 | +            if ($url[strlen($url) - 1] !== '/') { | |
| 144 | + $url .= '/'; | |
| 145 | + } | |
| 146 | + | |
| 147 | +            $response->setHeader('Content-Location', $url . $tag->getId()); | |
| 148 | + | |
| 149 | + // created | |
| 150 | + $response->setStatus(201); | |
| 151 | + return false; | |
| 152 | + } | |
| 153 | + } | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * Creates a new tag | |
| 157 | + * | |
| 158 | + * @param string $data JSON encoded string containing the properties of the tag to create | |
| 159 | + * @param string $contentType content type of the data | |
| 160 | + * @return ISystemTag newly created system tag | |
| 161 | + * | |
| 162 | + * @throws BadRequest if a field was missing | |
| 163 | + * @throws Conflict if a tag with the same properties already exists | |
| 164 | + * @throws UnsupportedMediaType if the content type is not supported | |
| 165 | + */ | |
| 166 | +    private function createTag($data, $contentType = 'application/json') { | |
| 167 | +        if (explode(';', $contentType)[0] === 'application/json') { | |
| 168 | + $data = json_decode($data, true); | |
| 169 | +        } else { | |
| 170 | + throw new UnsupportedMediaType(); | |
| 171 | + } | |
| 172 | + | |
| 173 | +        if (!isset($data['name'])) { | |
| 174 | +            throw new BadRequest('Missing "name" attribute'); | |
| 175 | + } | |
| 176 | + | |
| 177 | + $tagName = $data['name']; | |
| 178 | + $userVisible = true; | |
| 179 | + $userAssignable = true; | |
| 180 | + | |
| 181 | +        if (isset($data['userVisible'])) { | |
| 182 | + $userVisible = (bool)$data['userVisible']; | |
| 183 | + } | |
| 184 | + | |
| 185 | +        if (isset($data['userAssignable'])) { | |
| 186 | + $userAssignable = (bool)$data['userAssignable']; | |
| 187 | + } | |
| 188 | + | |
| 189 | + $groups = []; | |
| 190 | +        if (isset($data['groups'])) { | |
| 191 | + $groups = $data['groups']; | |
| 192 | +            if (is_string($groups)) { | |
| 193 | +                $groups = explode('|', $groups); | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | +        if($userVisible === false || $userAssignable === false || !empty($groups)) { | |
| 198 | +            if(!$this->userSession->isLoggedIn() || !$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 199 | +                throw new BadRequest('Not sufficient permissions'); | |
| 200 | + } | |
| 201 | + } | |
| 202 | + | |
| 203 | +        try { | |
| 204 | + $tag = $this->tagManager->createTag($tagName, $userVisible, $userAssignable); | |
| 205 | +            if (!empty($groups)) { | |
| 206 | + $this->tagManager->setTagGroups($tag, $groups); | |
| 207 | + } | |
| 208 | + return $tag; | |
| 209 | +        } catch (TagAlreadyExistsException $e) { | |
| 210 | +            throw new Conflict('Tag already exists', 0, $e); | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 214 | + | |
| 215 | + /** | |
| 216 | + * Retrieves system tag properties | |
| 217 | + * | |
| 218 | + * @param PropFind $propFind | |
| 219 | + * @param \Sabre\DAV\INode $node | |
| 220 | + */ | |
| 221 | + public function handleGetProperties( | |
| 222 | + PropFind $propFind, | |
| 223 | + \Sabre\DAV\INode $node | |
| 224 | +    ) { | |
| 225 | +        if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagMappingNode)) { | |
| 226 | + return; | |
| 227 | + } | |
| 228 | + | |
| 229 | +        $propFind->handle(self::ID_PROPERTYNAME, function() use ($node) { | |
| 230 | + return $node->getSystemTag()->getId(); | |
| 231 | + }); | |
| 232 | + | |
| 233 | +        $propFind->handle(self::DISPLAYNAME_PROPERTYNAME, function() use ($node) { | |
| 234 | + return $node->getSystemTag()->getName(); | |
| 235 | + }); | |
| 236 | + | |
| 237 | +        $propFind->handle(self::USERVISIBLE_PROPERTYNAME, function() use ($node) { | |
| 238 | + return $node->getSystemTag()->isUserVisible() ? 'true' : 'false'; | |
| 239 | + }); | |
| 240 | + | |
| 241 | +        $propFind->handle(self::USERASSIGNABLE_PROPERTYNAME, function() use ($node) { | |
| 242 | + // this is the tag's inherent property "is user assignable" | |
| 243 | + return $node->getSystemTag()->isUserAssignable() ? 'true' : 'false'; | |
| 244 | + }); | |
| 245 | + | |
| 246 | +        $propFind->handle(self::CANASSIGN_PROPERTYNAME, function() use ($node) { | |
| 247 | + // this is the effective permission for the current user | |
| 248 | + return $this->tagManager->canUserAssignTag($node->getSystemTag(), $this->userSession->getUser()) ? 'true' : 'false'; | |
| 249 | + }); | |
| 250 | + | |
| 251 | +        $propFind->handle(self::GROUPS_PROPERTYNAME, function() use ($node) { | |
| 252 | +            if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 253 | + // property only available for admins | |
| 254 | + throw new Forbidden(); | |
| 255 | + } | |
| 256 | + $groups = []; | |
| 257 | + // no need to retrieve groups for namespaces that don't qualify | |
| 258 | +            if ($node->getSystemTag()->isUserVisible() && !$node->getSystemTag()->isUserAssignable()) { | |
| 259 | + $groups = $this->tagManager->getTagGroups($node->getSystemTag()); | |
| 260 | + } | |
| 261 | +            return implode('|', $groups); | |
| 262 | + }); | |
| 263 | + } | |
| 264 | + | |
| 265 | + /** | |
| 266 | + * Updates tag attributes | |
| 267 | + * | |
| 268 | + * @param string $path | |
| 269 | + * @param PropPatch $propPatch | |
| 270 | + * | |
| 271 | + * @return void | |
| 272 | + */ | |
| 273 | +    public function handleUpdateProperties($path, PropPatch $propPatch) { | |
| 274 | + $propPatch->handle([ | |
| 275 | + self::DISPLAYNAME_PROPERTYNAME, | |
| 276 | + self::USERVISIBLE_PROPERTYNAME, | |
| 277 | + self::USERASSIGNABLE_PROPERTYNAME, | |
| 278 | + self::GROUPS_PROPERTYNAME, | |
| 279 | +        ], function($props) use ($path) { | |
| 280 | + $node = $this->server->tree->getNodeForPath($path); | |
| 281 | +            if (!($node instanceof SystemTagNode)) { | |
| 282 | + return; | |
| 283 | + } | |
| 284 | + | |
| 285 | + $tag = $node->getSystemTag(); | |
| 286 | + $name = $tag->getName(); | |
| 287 | + $userVisible = $tag->isUserVisible(); | |
| 288 | + $userAssignable = $tag->isUserAssignable(); | |
| 289 | + | |
| 290 | + $updateTag = false; | |
| 291 | + | |
| 292 | +            if (isset($props[self::DISPLAYNAME_PROPERTYNAME])) { | |
| 293 | + $name = $props[self::DISPLAYNAME_PROPERTYNAME]; | |
| 294 | + $updateTag = true; | |
| 295 | + } | |
| 296 | + | |
| 297 | +            if (isset($props[self::USERVISIBLE_PROPERTYNAME])) { | |
| 298 | + $propValue = $props[self::USERVISIBLE_PROPERTYNAME]; | |
| 299 | + $userVisible = ($propValue !== 'false' && $propValue !== '0'); | |
| 300 | + $updateTag = true; | |
| 301 | + } | |
| 302 | + | |
| 303 | +            if (isset($props[self::USERASSIGNABLE_PROPERTYNAME])) { | |
| 304 | + $propValue = $props[self::USERASSIGNABLE_PROPERTYNAME]; | |
| 305 | + $userAssignable = ($propValue !== 'false' && $propValue !== '0'); | |
| 306 | + $updateTag = true; | |
| 307 | + } | |
| 308 | + | |
| 309 | +            if (isset($props[self::GROUPS_PROPERTYNAME])) { | |
| 310 | +                if (!$this->groupManager->isAdmin($this->userSession->getUser()->getUID())) { | |
| 311 | + // property only available for admins | |
| 312 | + throw new Forbidden(); | |
| 313 | + } | |
| 314 | + | |
| 315 | + $propValue = $props[self::GROUPS_PROPERTYNAME]; | |
| 316 | +                $groupIds = explode('|', $propValue); | |
| 317 | + $this->tagManager->setTagGroups($tag, $groupIds); | |
| 318 | + } | |
| 319 | + | |
| 320 | +            if ($updateTag) { | |
| 321 | + $node->update($name, $userVisible, $userAssignable); | |
| 322 | + } | |
| 323 | + | |
| 324 | + return true; | |
| 325 | + }); | |
| 326 | + | |
| 327 | + } | |
| 328 | 328 | } | 
| @@ -26,13 +26,11 @@ | ||
| 26 | 26 | use Sabre\DAV\Exception\NotFound; | 
| 27 | 27 | use Sabre\DAV\Exception\BadRequest; | 
| 28 | 28 | use Sabre\DAV\ICollection; | 
| 29 | - | |
| 30 | 29 | use OCP\SystemTag\ISystemTagManager; | 
| 31 | 30 | use OCP\SystemTag\ISystemTag; | 
| 32 | 31 | use OCP\SystemTag\TagNotFoundException; | 
| 33 | 32 | use OCP\IGroupManager; | 
| 34 | 33 | use OCP\IUserSession; | 
| 35 | -use OC\User\NoUserException; | |
| 36 | 34 | |
| 37 | 35 |  class SystemTagsByIdCollection implements ICollection { | 
| 38 | 36 | |
| @@ -37,144 +37,144 @@ | ||
| 37 | 37 | |
| 38 | 38 |  class SystemTagsByIdCollection implements ICollection { | 
| 39 | 39 | |
| 40 | - /** | |
| 41 | - * @var ISystemTagManager | |
| 42 | - */ | |
| 43 | - private $tagManager; | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * @var IGroupManager | |
| 47 | - */ | |
| 48 | - private $groupManager; | |
| 49 | - | |
| 50 | - /** | |
| 51 | - * @var IUserSession | |
| 52 | - */ | |
| 53 | - private $userSession; | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * SystemTagsByIdCollection constructor. | |
| 57 | - * | |
| 58 | - * @param ISystemTagManager $tagManager | |
| 59 | - * @param IUserSession $userSession | |
| 60 | - * @param IGroupManager $groupManager | |
| 61 | - */ | |
| 62 | - public function __construct( | |
| 63 | - ISystemTagManager $tagManager, | |
| 64 | - IUserSession $userSession, | |
| 65 | - IGroupManager $groupManager | |
| 66 | -	) { | |
| 67 | - $this->tagManager = $tagManager; | |
| 68 | - $this->userSession = $userSession; | |
| 69 | - $this->groupManager = $groupManager; | |
| 70 | - } | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * Returns whether the currently logged in user is an administrator | |
| 74 | - * | |
| 75 | - * @return bool true if the user is an admin | |
| 76 | - */ | |
| 77 | -	private function isAdmin() { | |
| 78 | - $user = $this->userSession->getUser(); | |
| 79 | -		if ($user !== null) { | |
| 80 | - return $this->groupManager->isAdmin($user->getUID()); | |
| 81 | - } | |
| 82 | - return false; | |
| 83 | - } | |
| 84 | - | |
| 85 | - /** | |
| 86 | - * @param string $name | |
| 87 | - * @param resource|string $data Initial payload | |
| 88 | - * @throws Forbidden | |
| 89 | - */ | |
| 90 | -	function createFile($name, $data = null) { | |
| 91 | -		throw new Forbidden('Cannot create tags by id'); | |
| 92 | - } | |
| 93 | - | |
| 94 | - /** | |
| 95 | - * @param string $name | |
| 96 | - */ | |
| 97 | -	function createDirectory($name) { | |
| 98 | -		throw new Forbidden('Permission denied to create collections'); | |
| 99 | - } | |
| 100 | - | |
| 101 | - /** | |
| 102 | - * @param string $name | |
| 103 | - */ | |
| 104 | -	function getChild($name) { | |
| 105 | -		try { | |
| 106 | - $tag = $this->tagManager->getTagsByIds([$name]); | |
| 107 | - $tag = current($tag); | |
| 108 | -			if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { | |
| 109 | -				throw new NotFound('Tag with id ' . $name . ' not found'); | |
| 110 | - } | |
| 111 | - return $this->makeNode($tag); | |
| 112 | -		} catch (\InvalidArgumentException $e) { | |
| 113 | -			throw new BadRequest('Invalid tag id', 0, $e); | |
| 114 | -		} catch (TagNotFoundException $e) { | |
| 115 | -			throw new NotFound('Tag with id ' . $name . ' not found', 0, $e); | |
| 116 | - } | |
| 117 | - } | |
| 118 | - | |
| 119 | -	function getChildren() { | |
| 120 | - $visibilityFilter = true; | |
| 121 | -		if ($this->isAdmin()) { | |
| 122 | - $visibilityFilter = null; | |
| 123 | - } | |
| 124 | - | |
| 125 | - $tags = $this->tagManager->getAllTags($visibilityFilter); | |
| 126 | -		return array_map(function($tag) { | |
| 127 | - return $this->makeNode($tag); | |
| 128 | - }, $tags); | |
| 129 | - } | |
| 130 | - | |
| 131 | - /** | |
| 132 | - * @param string $name | |
| 133 | - */ | |
| 134 | -	function childExists($name) { | |
| 135 | -		try { | |
| 136 | - $tag = $this->tagManager->getTagsByIds([$name]); | |
| 137 | - $tag = current($tag); | |
| 138 | -			if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { | |
| 139 | - return false; | |
| 140 | - } | |
| 141 | - return true; | |
| 142 | -		} catch (\InvalidArgumentException $e) { | |
| 143 | -			throw new BadRequest('Invalid tag id', 0, $e); | |
| 144 | -		} catch (TagNotFoundException $e) { | |
| 145 | - return false; | |
| 146 | - } | |
| 147 | - } | |
| 148 | - | |
| 149 | -	function delete() { | |
| 150 | -		throw new Forbidden('Permission denied to delete this collection'); | |
| 151 | - } | |
| 152 | - | |
| 153 | -	function getName() { | |
| 154 | - return 'systemtags'; | |
| 155 | - } | |
| 156 | - | |
| 157 | -	function setName($name) { | |
| 158 | -		throw new Forbidden('Permission denied to rename this collection'); | |
| 159 | - } | |
| 160 | - | |
| 161 | - /** | |
| 162 | - * Returns the last modification time, as a unix timestamp | |
| 163 | - * | |
| 164 | - * @return int | |
| 165 | - */ | |
| 166 | -	function getLastModified() { | |
| 167 | - return null; | |
| 168 | - } | |
| 169 | - | |
| 170 | - /** | |
| 171 | - * Create a sabre node for the given system tag | |
| 172 | - * | |
| 173 | - * @param ISystemTag $tag | |
| 174 | - * | |
| 175 | - * @return SystemTagNode | |
| 176 | - */ | |
| 177 | -	private function makeNode(ISystemTag $tag) { | |
| 178 | - return new SystemTagNode($tag, $this->userSession->getUser(), $this->isAdmin(), $this->tagManager); | |
| 179 | - } | |
| 40 | + /** | |
| 41 | + * @var ISystemTagManager | |
| 42 | + */ | |
| 43 | + private $tagManager; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * @var IGroupManager | |
| 47 | + */ | |
| 48 | + private $groupManager; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * @var IUserSession | |
| 52 | + */ | |
| 53 | + private $userSession; | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * SystemTagsByIdCollection constructor. | |
| 57 | + * | |
| 58 | + * @param ISystemTagManager $tagManager | |
| 59 | + * @param IUserSession $userSession | |
| 60 | + * @param IGroupManager $groupManager | |
| 61 | + */ | |
| 62 | + public function __construct( | |
| 63 | + ISystemTagManager $tagManager, | |
| 64 | + IUserSession $userSession, | |
| 65 | + IGroupManager $groupManager | |
| 66 | +    ) { | |
| 67 | + $this->tagManager = $tagManager; | |
| 68 | + $this->userSession = $userSession; | |
| 69 | + $this->groupManager = $groupManager; | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Returns whether the currently logged in user is an administrator | |
| 74 | + * | |
| 75 | + * @return bool true if the user is an admin | |
| 76 | + */ | |
| 77 | +    private function isAdmin() { | |
| 78 | + $user = $this->userSession->getUser(); | |
| 79 | +        if ($user !== null) { | |
| 80 | + return $this->groupManager->isAdmin($user->getUID()); | |
| 81 | + } | |
| 82 | + return false; | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * @param string $name | |
| 87 | + * @param resource|string $data Initial payload | |
| 88 | + * @throws Forbidden | |
| 89 | + */ | |
| 90 | +    function createFile($name, $data = null) { | |
| 91 | +        throw new Forbidden('Cannot create tags by id'); | |
| 92 | + } | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * @param string $name | |
| 96 | + */ | |
| 97 | +    function createDirectory($name) { | |
| 98 | +        throw new Forbidden('Permission denied to create collections'); | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * @param string $name | |
| 103 | + */ | |
| 104 | +    function getChild($name) { | |
| 105 | +        try { | |
| 106 | + $tag = $this->tagManager->getTagsByIds([$name]); | |
| 107 | + $tag = current($tag); | |
| 108 | +            if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { | |
| 109 | +                throw new NotFound('Tag with id ' . $name . ' not found'); | |
| 110 | + } | |
| 111 | + return $this->makeNode($tag); | |
| 112 | +        } catch (\InvalidArgumentException $e) { | |
| 113 | +            throw new BadRequest('Invalid tag id', 0, $e); | |
| 114 | +        } catch (TagNotFoundException $e) { | |
| 115 | +            throw new NotFound('Tag with id ' . $name . ' not found', 0, $e); | |
| 116 | + } | |
| 117 | + } | |
| 118 | + | |
| 119 | +    function getChildren() { | |
| 120 | + $visibilityFilter = true; | |
| 121 | +        if ($this->isAdmin()) { | |
| 122 | + $visibilityFilter = null; | |
| 123 | + } | |
| 124 | + | |
| 125 | + $tags = $this->tagManager->getAllTags($visibilityFilter); | |
| 126 | +        return array_map(function($tag) { | |
| 127 | + return $this->makeNode($tag); | |
| 128 | + }, $tags); | |
| 129 | + } | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * @param string $name | |
| 133 | + */ | |
| 134 | +    function childExists($name) { | |
| 135 | +        try { | |
| 136 | + $tag = $this->tagManager->getTagsByIds([$name]); | |
| 137 | + $tag = current($tag); | |
| 138 | +            if (!$this->tagManager->canUserSeeTag($tag, $this->userSession->getUser())) { | |
| 139 | + return false; | |
| 140 | + } | |
| 141 | + return true; | |
| 142 | +        } catch (\InvalidArgumentException $e) { | |
| 143 | +            throw new BadRequest('Invalid tag id', 0, $e); | |
| 144 | +        } catch (TagNotFoundException $e) { | |
| 145 | + return false; | |
| 146 | + } | |
| 147 | + } | |
| 148 | + | |
| 149 | +    function delete() { | |
| 150 | +        throw new Forbidden('Permission denied to delete this collection'); | |
| 151 | + } | |
| 152 | + | |
| 153 | +    function getName() { | |
| 154 | + return 'systemtags'; | |
| 155 | + } | |
| 156 | + | |
| 157 | +    function setName($name) { | |
| 158 | +        throw new Forbidden('Permission denied to rename this collection'); | |
| 159 | + } | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * Returns the last modification time, as a unix timestamp | |
| 163 | + * | |
| 164 | + * @return int | |
| 165 | + */ | |
| 166 | +    function getLastModified() { | |
| 167 | + return null; | |
| 168 | + } | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * Create a sabre node for the given system tag | |
| 172 | + * | |
| 173 | + * @param ISystemTag $tag | |
| 174 | + * | |
| 175 | + * @return SystemTagNode | |
| 176 | + */ | |
| 177 | +    private function makeNode(ISystemTag $tag) { | |
| 178 | + return new SystemTagNode($tag, $this->userSession->getUser(), $this->isAdmin(), $this->tagManager); | |
| 179 | + } | |
| 180 | 180 | } | 
| @@ -26,7 +26,6 @@ | ||
| 26 | 26 | use Sabre\DAV\Exception\BadRequest; | 
| 27 | 27 | use Sabre\DAV\Exception\PreconditionFailed; | 
| 28 | 28 | use Sabre\DAV\ICollection; | 
| 29 | - | |
| 30 | 29 | use OCP\SystemTag\ISystemTagManager; | 
| 31 | 30 | use OCP\SystemTag\ISystemTagObjectMapper; | 
| 32 | 31 | use OCP\SystemTag\ISystemTag; | 
| @@ -39,169 +39,169 @@ | ||
| 39 | 39 | */ | 
| 40 | 40 |  class SystemTagsObjectMappingCollection implements ICollection { | 
| 41 | 41 | |
| 42 | - /** | |
| 43 | - * @var string | |
| 44 | - */ | |
| 45 | - private $objectId; | |
| 46 | - | |
| 47 | - /** | |
| 48 | - * @var string | |
| 49 | - */ | |
| 50 | - private $objectType; | |
| 51 | - | |
| 52 | - /** | |
| 53 | - * @var ISystemTagManager | |
| 54 | - */ | |
| 55 | - private $tagManager; | |
| 56 | - | |
| 57 | - /** | |
| 58 | - * @var ISystemTagObjectMapper | |
| 59 | - */ | |
| 60 | - private $tagMapper; | |
| 61 | - | |
| 62 | - /** | |
| 63 | - * User | |
| 64 | - * | |
| 65 | - * @var IUser | |
| 66 | - */ | |
| 67 | - private $user; | |
| 68 | - | |
| 69 | - | |
| 70 | - /** | |
| 71 | - * Constructor | |
| 72 | - * | |
| 73 | - * @param string $objectId object id | |
| 74 | - * @param string $objectType object type | |
| 75 | - * @param IUser $user user | |
| 76 | - * @param ISystemTagManager $tagManager tag manager | |
| 77 | - * @param ISystemTagObjectMapper $tagMapper tag mapper | |
| 78 | - */ | |
| 79 | - public function __construct( | |
| 80 | - $objectId, | |
| 81 | - $objectType, | |
| 82 | - IUser $user, | |
| 83 | - ISystemTagManager $tagManager, | |
| 84 | - ISystemTagObjectMapper $tagMapper | |
| 85 | -	) { | |
| 86 | - $this->tagManager = $tagManager; | |
| 87 | - $this->tagMapper = $tagMapper; | |
| 88 | - $this->objectId = $objectId; | |
| 89 | - $this->objectType = $objectType; | |
| 90 | - $this->user = $user; | |
| 91 | - } | |
| 92 | - | |
| 93 | -	function createFile($tagId, $data = null) { | |
| 94 | -		try { | |
| 95 | - $tags = $this->tagManager->getTagsByIds([$tagId]); | |
| 96 | - $tag = current($tags); | |
| 97 | -			if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 98 | -				throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); | |
| 99 | - } | |
| 100 | -			if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { | |
| 101 | -				throw new Forbidden('No permission to assign tag ' . $tagId); | |
| 102 | - } | |
| 103 | - | |
| 104 | - $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); | |
| 105 | -		} catch (TagNotFoundException $e) { | |
| 106 | -			throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); | |
| 107 | - } | |
| 108 | - } | |
| 109 | - | |
| 110 | -	function createDirectory($name) { | |
| 111 | -		throw new Forbidden('Permission denied to create collections'); | |
| 112 | - } | |
| 113 | - | |
| 114 | -	function getChild($tagId) { | |
| 115 | -		try { | |
| 116 | -			if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) { | |
| 117 | - $tag = $this->tagManager->getTagsByIds([$tagId]); | |
| 118 | - $tag = current($tag); | |
| 119 | -				if ($this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 120 | - return $this->makeNode($tag); | |
| 121 | - } | |
| 122 | - } | |
| 123 | -			throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId); | |
| 124 | -		} catch (\InvalidArgumentException $e) { | |
| 125 | -			throw new BadRequest('Invalid tag id', 0, $e); | |
| 126 | -		} catch (TagNotFoundException $e) { | |
| 127 | -			throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e); | |
| 128 | - } | |
| 129 | - } | |
| 130 | - | |
| 131 | -	function getChildren() { | |
| 132 | - $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); | |
| 133 | -		if (empty($tagIds)) { | |
| 134 | - return []; | |
| 135 | - } | |
| 136 | - $tags = $this->tagManager->getTagsByIds($tagIds); | |
| 137 | - | |
| 138 | - // filter out non-visible tags | |
| 139 | -		$tags = array_filter($tags, function($tag) { | |
| 140 | - return $this->tagManager->canUserSeeTag($tag, $this->user); | |
| 141 | - }); | |
| 142 | - | |
| 143 | -		return array_values(array_map(function($tag) { | |
| 144 | - return $this->makeNode($tag); | |
| 145 | - }, $tags)); | |
| 146 | - } | |
| 147 | - | |
| 148 | -	function childExists($tagId) { | |
| 149 | -		try { | |
| 150 | - $result = ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)); | |
| 151 | - | |
| 152 | -			if ($result) { | |
| 153 | - $tags = $this->tagManager->getTagsByIds([$tagId]); | |
| 154 | - $tag = current($tags); | |
| 155 | -				if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 156 | - return false; | |
| 157 | - } | |
| 158 | - } | |
| 159 | - | |
| 160 | - return $result; | |
| 161 | -		} catch (\InvalidArgumentException $e) { | |
| 162 | -			throw new BadRequest('Invalid tag id', 0, $e); | |
| 163 | -		} catch (TagNotFoundException $e) { | |
| 164 | - return false; | |
| 165 | - } | |
| 166 | - } | |
| 167 | - | |
| 168 | -	function delete() { | |
| 169 | -		throw new Forbidden('Permission denied to delete this collection'); | |
| 170 | - } | |
| 171 | - | |
| 172 | -	function getName() { | |
| 173 | - return $this->objectId; | |
| 174 | - } | |
| 175 | - | |
| 176 | -	function setName($name) { | |
| 177 | -		throw new Forbidden('Permission denied to rename this collection'); | |
| 178 | - } | |
| 179 | - | |
| 180 | - /** | |
| 181 | - * Returns the last modification time, as a unix timestamp | |
| 182 | - * | |
| 183 | - * @return int | |
| 184 | - */ | |
| 185 | -	function getLastModified() { | |
| 186 | - return null; | |
| 187 | - } | |
| 188 | - | |
| 189 | - /** | |
| 190 | - * Create a sabre node for the mapping of the | |
| 191 | - * given system tag to the collection's object | |
| 192 | - * | |
| 193 | - * @param ISystemTag $tag | |
| 194 | - * | |
| 195 | - * @return SystemTagMappingNode | |
| 196 | - */ | |
| 197 | -	private function makeNode(ISystemTag $tag) { | |
| 198 | - return new SystemTagMappingNode( | |
| 199 | - $tag, | |
| 200 | - $this->objectId, | |
| 201 | - $this->objectType, | |
| 202 | - $this->user, | |
| 203 | - $this->tagManager, | |
| 204 | - $this->tagMapper | |
| 205 | - ); | |
| 206 | - } | |
| 42 | + /** | |
| 43 | + * @var string | |
| 44 | + */ | |
| 45 | + private $objectId; | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * @var string | |
| 49 | + */ | |
| 50 | + private $objectType; | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * @var ISystemTagManager | |
| 54 | + */ | |
| 55 | + private $tagManager; | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * @var ISystemTagObjectMapper | |
| 59 | + */ | |
| 60 | + private $tagMapper; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * User | |
| 64 | + * | |
| 65 | + * @var IUser | |
| 66 | + */ | |
| 67 | + private $user; | |
| 68 | + | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Constructor | |
| 72 | + * | |
| 73 | + * @param string $objectId object id | |
| 74 | + * @param string $objectType object type | |
| 75 | + * @param IUser $user user | |
| 76 | + * @param ISystemTagManager $tagManager tag manager | |
| 77 | + * @param ISystemTagObjectMapper $tagMapper tag mapper | |
| 78 | + */ | |
| 79 | + public function __construct( | |
| 80 | + $objectId, | |
| 81 | + $objectType, | |
| 82 | + IUser $user, | |
| 83 | + ISystemTagManager $tagManager, | |
| 84 | + ISystemTagObjectMapper $tagMapper | |
| 85 | +    ) { | |
| 86 | + $this->tagManager = $tagManager; | |
| 87 | + $this->tagMapper = $tagMapper; | |
| 88 | + $this->objectId = $objectId; | |
| 89 | + $this->objectType = $objectType; | |
| 90 | + $this->user = $user; | |
| 91 | + } | |
| 92 | + | |
| 93 | +    function createFile($tagId, $data = null) { | |
| 94 | +        try { | |
| 95 | + $tags = $this->tagManager->getTagsByIds([$tagId]); | |
| 96 | + $tag = current($tags); | |
| 97 | +            if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 98 | +                throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); | |
| 99 | + } | |
| 100 | +            if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { | |
| 101 | +                throw new Forbidden('No permission to assign tag ' . $tagId); | |
| 102 | + } | |
| 103 | + | |
| 104 | + $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); | |
| 105 | +        } catch (TagNotFoundException $e) { | |
| 106 | +            throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); | |
| 107 | + } | |
| 108 | + } | |
| 109 | + | |
| 110 | +    function createDirectory($name) { | |
| 111 | +        throw new Forbidden('Permission denied to create collections'); | |
| 112 | + } | |
| 113 | + | |
| 114 | +    function getChild($tagId) { | |
| 115 | +        try { | |
| 116 | +            if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) { | |
| 117 | + $tag = $this->tagManager->getTagsByIds([$tagId]); | |
| 118 | + $tag = current($tag); | |
| 119 | +                if ($this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 120 | + return $this->makeNode($tag); | |
| 121 | + } | |
| 122 | + } | |
| 123 | +            throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId); | |
| 124 | +        } catch (\InvalidArgumentException $e) { | |
| 125 | +            throw new BadRequest('Invalid tag id', 0, $e); | |
| 126 | +        } catch (TagNotFoundException $e) { | |
| 127 | +            throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e); | |
| 128 | + } | |
| 129 | + } | |
| 130 | + | |
| 131 | +    function getChildren() { | |
| 132 | + $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); | |
| 133 | +        if (empty($tagIds)) { | |
| 134 | + return []; | |
| 135 | + } | |
| 136 | + $tags = $this->tagManager->getTagsByIds($tagIds); | |
| 137 | + | |
| 138 | + // filter out non-visible tags | |
| 139 | +        $tags = array_filter($tags, function($tag) { | |
| 140 | + return $this->tagManager->canUserSeeTag($tag, $this->user); | |
| 141 | + }); | |
| 142 | + | |
| 143 | +        return array_values(array_map(function($tag) { | |
| 144 | + return $this->makeNode($tag); | |
| 145 | + }, $tags)); | |
| 146 | + } | |
| 147 | + | |
| 148 | +    function childExists($tagId) { | |
| 149 | +        try { | |
| 150 | + $result = ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)); | |
| 151 | + | |
| 152 | +            if ($result) { | |
| 153 | + $tags = $this->tagManager->getTagsByIds([$tagId]); | |
| 154 | + $tag = current($tags); | |
| 155 | +                if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { | |
| 156 | + return false; | |
| 157 | + } | |
| 158 | + } | |
| 159 | + | |
| 160 | + return $result; | |
| 161 | +        } catch (\InvalidArgumentException $e) { | |
| 162 | +            throw new BadRequest('Invalid tag id', 0, $e); | |
| 163 | +        } catch (TagNotFoundException $e) { | |
| 164 | + return false; | |
| 165 | + } | |
| 166 | + } | |
| 167 | + | |
| 168 | +    function delete() { | |
| 169 | +        throw new Forbidden('Permission denied to delete this collection'); | |
| 170 | + } | |
| 171 | + | |
| 172 | +    function getName() { | |
| 173 | + return $this->objectId; | |
| 174 | + } | |
| 175 | + | |
| 176 | +    function setName($name) { | |
| 177 | +        throw new Forbidden('Permission denied to rename this collection'); | |
| 178 | + } | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * Returns the last modification time, as a unix timestamp | |
| 182 | + * | |
| 183 | + * @return int | |
| 184 | + */ | |
| 185 | +    function getLastModified() { | |
| 186 | + return null; | |
| 187 | + } | |
| 188 | + | |
| 189 | + /** | |
| 190 | + * Create a sabre node for the mapping of the | |
| 191 | + * given system tag to the collection's object | |
| 192 | + * | |
| 193 | + * @param ISystemTag $tag | |
| 194 | + * | |
| 195 | + * @return SystemTagMappingNode | |
| 196 | + */ | |
| 197 | +    private function makeNode(ISystemTag $tag) { | |
| 198 | + return new SystemTagMappingNode( | |
| 199 | + $tag, | |
| 200 | + $this->objectId, | |
| 201 | + $this->objectType, | |
| 202 | + $this->user, | |
| 203 | + $this->tagManager, | |
| 204 | + $this->tagMapper | |
| 205 | + ); | |
| 206 | + } | |
| 207 | 207 | } | 
| @@ -26,7 +26,6 @@ | ||
| 26 | 26 | use Sabre\DAV\Exception\MethodNotAllowed; | 
| 27 | 27 | use Sabre\DAV\Exception\NotFound; | 
| 28 | 28 | use Sabre\DAV\ICollection; | 
| 29 | - | |
| 30 | 29 | use OCP\SystemTag\ISystemTagManager; | 
| 31 | 30 | use OCP\SystemTag\ISystemTagObjectMapper; | 
| 32 | 31 | use OCP\IUserSession; | 
| @@ -39,136 +39,136 @@ | ||
| 39 | 39 | */ | 
| 40 | 40 |  class SystemTagsObjectTypeCollection implements ICollection { | 
| 41 | 41 | |
| 42 | - /** | |
| 43 | - * @var string | |
| 44 | - */ | |
| 45 | - private $objectType; | |
| 46 | - | |
| 47 | - /** | |
| 48 | - * @var ISystemTagManager | |
| 49 | - */ | |
| 50 | - private $tagManager; | |
| 51 | - | |
| 52 | - /** | |
| 53 | - * @var ISystemTagObjectMapper | |
| 54 | - */ | |
| 55 | - private $tagMapper; | |
| 56 | - | |
| 57 | - /** | |
| 58 | - * @var IGroupManager | |
| 59 | - */ | |
| 60 | - private $groupManager; | |
| 61 | - | |
| 62 | - /** | |
| 63 | - * @var IUserSession | |
| 64 | - */ | |
| 65 | - private $userSession; | |
| 66 | - | |
| 67 | - /** | |
| 68 | - * @var \Closure | |
| 69 | - **/ | |
| 70 | - protected $childExistsFunction; | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * Constructor | |
| 74 | - * | |
| 75 | - * @param string $objectType object type | |
| 76 | - * @param ISystemTagManager $tagManager | |
| 77 | - * @param ISystemTagObjectMapper $tagMapper | |
| 78 | - * @param IUserSession $userSession | |
| 79 | - * @param IGroupManager $groupManager | |
| 80 | - * @param \Closure $childExistsFunction | |
| 81 | - */ | |
| 82 | - public function __construct( | |
| 83 | - $objectType, | |
| 84 | - ISystemTagManager $tagManager, | |
| 85 | - ISystemTagObjectMapper $tagMapper, | |
| 86 | - IUserSession $userSession, | |
| 87 | - IGroupManager $groupManager, | |
| 88 | - \Closure $childExistsFunction | |
| 89 | -	) { | |
| 90 | - $this->tagManager = $tagManager; | |
| 91 | - $this->tagMapper = $tagMapper; | |
| 92 | - $this->objectType = $objectType; | |
| 93 | - $this->userSession = $userSession; | |
| 94 | - $this->groupManager = $groupManager; | |
| 95 | - $this->childExistsFunction = $childExistsFunction; | |
| 96 | - } | |
| 97 | - | |
| 98 | - /** | |
| 99 | - * @param string $name | |
| 100 | - * @param resource|string $data Initial payload | |
| 101 | - * @return null|string | |
| 102 | - * @throws Forbidden | |
| 103 | - */ | |
| 104 | -	function createFile($name, $data = null) { | |
| 105 | -		throw new Forbidden('Permission denied to create nodes'); | |
| 106 | - } | |
| 107 | - | |
| 108 | - /** | |
| 109 | - * @param string $name | |
| 110 | - * @throws Forbidden | |
| 111 | - */ | |
| 112 | -	function createDirectory($name) { | |
| 113 | -		throw new Forbidden('Permission denied to create collections'); | |
| 114 | - } | |
| 115 | - | |
| 116 | - /** | |
| 117 | - * @param string $objectId | |
| 118 | - * @return SystemTagsObjectMappingCollection | |
| 119 | - * @throws NotFound | |
| 120 | - */ | |
| 121 | -	function getChild($objectId) { | |
| 122 | - // make sure the object exists and is reachable | |
| 123 | -		if(!$this->childExists($objectId)) { | |
| 124 | -			throw new NotFound('Entity does not exist or is not available'); | |
| 125 | - } | |
| 126 | - return new SystemTagsObjectMappingCollection( | |
| 127 | - $objectId, | |
| 128 | - $this->objectType, | |
| 129 | - $this->userSession->getUser(), | |
| 130 | - $this->tagManager, | |
| 131 | - $this->tagMapper | |
| 132 | - ); | |
| 133 | - } | |
| 134 | - | |
| 135 | -	function getChildren() { | |
| 136 | - // do not list object ids | |
| 137 | - throw new MethodNotAllowed(); | |
| 138 | - } | |
| 139 | - | |
| 140 | - /** | |
| 141 | - * Checks if a child-node with the specified name exists | |
| 142 | - * | |
| 143 | - * @param string $name | |
| 144 | - * @return bool | |
| 145 | - */ | |
| 146 | -	function childExists($name) { | |
| 147 | - return call_user_func($this->childExistsFunction, $name); | |
| 148 | - } | |
| 149 | - | |
| 150 | -	function delete() { | |
| 151 | -		throw new Forbidden('Permission denied to delete this collection'); | |
| 152 | - } | |
| 153 | - | |
| 154 | -	function getName() { | |
| 155 | - return $this->objectType; | |
| 156 | - } | |
| 157 | - | |
| 158 | - /** | |
| 159 | - * @param string $name | |
| 160 | - * @throws Forbidden | |
| 161 | - */ | |
| 162 | -	function setName($name) { | |
| 163 | -		throw new Forbidden('Permission denied to rename this collection'); | |
| 164 | - } | |
| 165 | - | |
| 166 | - /** | |
| 167 | - * Returns the last modification time, as a unix timestamp | |
| 168 | - * | |
| 169 | - * @return int | |
| 170 | - */ | |
| 171 | -	function getLastModified() { | |
| 172 | - return null; | |
| 173 | - } | |
| 42 | + /** | |
| 43 | + * @var string | |
| 44 | + */ | |
| 45 | + private $objectType; | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * @var ISystemTagManager | |
| 49 | + */ | |
| 50 | + private $tagManager; | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * @var ISystemTagObjectMapper | |
| 54 | + */ | |
| 55 | + private $tagMapper; | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * @var IGroupManager | |
| 59 | + */ | |
| 60 | + private $groupManager; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * @var IUserSession | |
| 64 | + */ | |
| 65 | + private $userSession; | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * @var \Closure | |
| 69 | + **/ | |
| 70 | + protected $childExistsFunction; | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Constructor | |
| 74 | + * | |
| 75 | + * @param string $objectType object type | |
| 76 | + * @param ISystemTagManager $tagManager | |
| 77 | + * @param ISystemTagObjectMapper $tagMapper | |
| 78 | + * @param IUserSession $userSession | |
| 79 | + * @param IGroupManager $groupManager | |
| 80 | + * @param \Closure $childExistsFunction | |
| 81 | + */ | |
| 82 | + public function __construct( | |
| 83 | + $objectType, | |
| 84 | + ISystemTagManager $tagManager, | |
| 85 | + ISystemTagObjectMapper $tagMapper, | |
| 86 | + IUserSession $userSession, | |
| 87 | + IGroupManager $groupManager, | |
| 88 | + \Closure $childExistsFunction | |
| 89 | +    ) { | |
| 90 | + $this->tagManager = $tagManager; | |
| 91 | + $this->tagMapper = $tagMapper; | |
| 92 | + $this->objectType = $objectType; | |
| 93 | + $this->userSession = $userSession; | |
| 94 | + $this->groupManager = $groupManager; | |
| 95 | + $this->childExistsFunction = $childExistsFunction; | |
| 96 | + } | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * @param string $name | |
| 100 | + * @param resource|string $data Initial payload | |
| 101 | + * @return null|string | |
| 102 | + * @throws Forbidden | |
| 103 | + */ | |
| 104 | +    function createFile($name, $data = null) { | |
| 105 | +        throw new Forbidden('Permission denied to create nodes'); | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * @param string $name | |
| 110 | + * @throws Forbidden | |
| 111 | + */ | |
| 112 | +    function createDirectory($name) { | |
| 113 | +        throw new Forbidden('Permission denied to create collections'); | |
| 114 | + } | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * @param string $objectId | |
| 118 | + * @return SystemTagsObjectMappingCollection | |
| 119 | + * @throws NotFound | |
| 120 | + */ | |
| 121 | +    function getChild($objectId) { | |
| 122 | + // make sure the object exists and is reachable | |
| 123 | +        if(!$this->childExists($objectId)) { | |
| 124 | +            throw new NotFound('Entity does not exist or is not available'); | |
| 125 | + } | |
| 126 | + return new SystemTagsObjectMappingCollection( | |
| 127 | + $objectId, | |
| 128 | + $this->objectType, | |
| 129 | + $this->userSession->getUser(), | |
| 130 | + $this->tagManager, | |
| 131 | + $this->tagMapper | |
| 132 | + ); | |
| 133 | + } | |
| 134 | + | |
| 135 | +    function getChildren() { | |
| 136 | + // do not list object ids | |
| 137 | + throw new MethodNotAllowed(); | |
| 138 | + } | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * Checks if a child-node with the specified name exists | |
| 142 | + * | |
| 143 | + * @param string $name | |
| 144 | + * @return bool | |
| 145 | + */ | |
| 146 | +    function childExists($name) { | |
| 147 | + return call_user_func($this->childExistsFunction, $name); | |
| 148 | + } | |
| 149 | + | |
| 150 | +    function delete() { | |
| 151 | +        throw new Forbidden('Permission denied to delete this collection'); | |
| 152 | + } | |
| 153 | + | |
| 154 | +    function getName() { | |
| 155 | + return $this->objectType; | |
| 156 | + } | |
| 157 | + | |
| 158 | + /** | |
| 159 | + * @param string $name | |
| 160 | + * @throws Forbidden | |
| 161 | + */ | |
| 162 | +    function setName($name) { | |
| 163 | +        throw new Forbidden('Permission denied to rename this collection'); | |
| 164 | + } | |
| 165 | + | |
| 166 | + /** | |
| 167 | + * Returns the last modification time, as a unix timestamp | |
| 168 | + * | |
| 169 | + * @return int | |
| 170 | + */ | |
| 171 | +    function getLastModified() { | |
| 172 | + return null; | |
| 173 | + } | |
| 174 | 174 | } |