Skip to content

Commit

Permalink
fix(psalm): systemtags
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Apr 28, 2023
1 parent 74ced3d commit 287da61
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 23 deletions.
12 changes: 6 additions & 6 deletions apps/dav/lib/SystemTag/SystemTagList.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright Copyright (c) 2023 Robin Appelman <robin@icewind.nl>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <vincent@nextcloud.com>
* @author Robin Appelman <robin@icewind.nl>
*
* @license AGPL-3.0
*
Expand All @@ -19,7 +17,6 @@
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\SystemTag;

Expand Down Expand Up @@ -49,7 +46,10 @@ public function __construct(array $tags, ISystemTagManager $tagManager, IUser $u
$this->user = $user;
}

public function getTags() {
/**
* @return ISystemTag[]
*/
public function getTags(): array {
return $this->tags;
}

Expand Down
5 changes: 5 additions & 0 deletions apps/dav/lib/SystemTag/SystemTagMappingNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ public function getName() {
* @param string $name The new name
*
* @throws MethodNotAllowed not allowed to rename node
*
* @return never
*/
public function setName($name) {
throw new MethodNotAllowed();
Expand All @@ -145,13 +147,16 @@ public function setName($name) {
/**
* Returns null, not supported
*
* @return null
*/
public function getLastModified() {
return null;
}

/**
* Delete tag to object association
*
* @return void
*/
public function delete() {
try {
Expand Down
9 changes: 8 additions & 1 deletion apps/dav/lib/SystemTag/SystemTagNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ public function getSystemTag() {
* @param string $name The new name
*
* @throws MethodNotAllowed not allowed to rename node
*
* @return never
*/
public function setName($name) {
throw new MethodNotAllowed();
Expand All @@ -114,11 +116,12 @@ public function setName($name) {
* @param string $name new tag name
* @param bool $userVisible user visible
* @param bool $userAssignable user assignable
*
* @throws NotFound whenever the given tag id does not exist
* @throws Forbidden whenever there is no permission to update said tag
* @throws Conflict whenever a tag already exists with the given attributes
*/
public function update($name, $userVisible, $userAssignable) {
public function update($name, $userVisible, $userAssignable): void {
try {
if (!$this->tagManager->canUserSeeTag($this->tag, $this->user)) {
throw new NotFound('Tag with id ' . $this->tag->getId() . ' does not exist');
Expand Down Expand Up @@ -151,11 +154,15 @@ public function update($name, $userVisible, $userAssignable) {
/**
* Returns null, not supported
*
* @return null
*/
public function getLastModified() {
return null;
}

/**
* @return void
*/
public function delete() {
try {
if (!$this->isAdmin) {
Expand Down
34 changes: 24 additions & 10 deletions apps/dav/lib/SystemTag/SystemTagPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Connector\Sabre\Node;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
Expand Down Expand Up @@ -81,9 +82,9 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
*/
protected $groupManager;

/** @var array<int, int[]> */
/** @var array<int, string[]> */
private array $cachedTagMappings = [];
/** @var array<int, ISystemTag> */
/** @var array<string, ISystemTag> */
private array $cachedTags = [];

private ISystemTagObjectMapper $tagMapper;
Expand Down Expand Up @@ -225,6 +226,8 @@ private function createTag($data, $contentType = 'application/json') {
*
* @param PropFind $propFind
* @param \Sabre\DAV\INode $node
*
* @return void
*/
public function handleGetProperties(
PropFind $propFind,
Expand Down Expand Up @@ -279,34 +282,42 @@ private function propfindForFile(PropFind $propFind, Node $node): void {
if ($node instanceof Directory
&& $propFind->getDepth() !== 0
&& !is_null($propFind->getStatus(self::SYSTEM_TAGS_PROPERTYNAME))) {
$fileIds = [$node->getId()];

// note: pre-fetching only supported for depth <= 1
$folderContent = $node->getNode()->getDirectoryListing();
$fileIds[] = (int)$node->getId();
foreach ($folderContent as $info) {
$fileIds[] = (int)$info->getId();
$fileIds[] = $info->getId();
}

$tags = $this->tagMapper->getTagIdsForObjects($fileIds, 'files');

$this->cachedTagMappings = $this->cachedTagMappings + $tags;
$emptyFileIds = array_diff($fileIds, array_keys($tags));

// also cache the ones that were not found
foreach ($emptyFileIds as $fileId) {
$this->cachedTagMappings[$fileId] = [];
}
}

$propFind->handle(self::SYSTEM_TAGS_PROPERTYNAME, function () use ($node) {
$tags = $this->getTagsForFile($node->getId());
return new SystemTagList($tags, $this->tagManager, $this->userSession->getUser());
$user = $this->userSession->getUser();
if ($user === null) {
return;
}

$tags = $this->getTagsForFile($node->getId(), $user);
return new SystemTagList($tags, $this->tagManager, $user);
});
}

/**
* @param int $fileId
* @return ISystemTag[]
*/
private function getTagsForFile(int $fileId): array {
$user = $this->userSession->getUser();
private function getTagsForFile(int $fileId, IUser $user): array {

if (isset($this->cachedTagMappings[$fileId])) {
$tagIds = $this->cachedTagMappings[$fileId];
} else {
Expand All @@ -318,20 +329,23 @@ private function getTagsForFile(int $fileId): array {
$tagIds = [];
}
}
$tags = array_filter(array_map(function($tagId) {

$tags = array_filter(array_map(function(string $tagId) {
return $this->cachedTags[$tagId] ?? null;
}, $tagIds));

$uncachedTagIds = array_filter($tagIds, function($tagId): bool {
$uncachedTagIds = array_filter($tagIds, function(string $tagId): bool {
return !isset($this->cachedTags[$tagId]);
});

if (count($uncachedTagIds)) {
$retrievedTags = $this->tagManager->getTagsByIds($uncachedTagIds);
foreach ($retrievedTags as $tag) {
$this->cachedTags[$tag->getId()] = $tag;
}
$tags += $retrievedTags;
}

return array_filter($tags, function(ISystemTag $tag) use ($user) {
return $this->tagManager->canUserSeeTag($tag, $user);
});
Expand Down
25 changes: 24 additions & 1 deletion apps/dav/lib/SystemTag/SystemTagsByIdCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,28 @@ private function isAdmin() {
/**
* @param string $name
* @param resource|string $data Initial payload
*
* @throws Forbidden
*
* @return never
*/
public function createFile($name, $data = null) {
throw new Forbidden('Cannot create tags by id');
}

/**
* @param string $name
*
* @return never
*/
public function createDirectory($name) {
throw new Forbidden('Permission denied to create collections');
}

/**
* @param string $name
*
* @return SystemTagNode
*/
public function getChild($name) {
try {
Expand All @@ -115,6 +122,11 @@ public function getChild($name) {
}
}

/**
* @return SystemTagNode[]
*
* @psalm-return array<SystemTagNode>
*/
public function getChildren() {
$visibilityFilter = true;
if ($this->isAdmin()) {
Expand Down Expand Up @@ -145,22 +157,33 @@ public function childExists($name) {
}
}

/**
* @return never
*/
public function delete() {
throw new Forbidden('Permission denied to delete this collection');
}

/**
* @return string
*
* @psalm-return 'systemtags'
*/
public function getName() {
return 'systemtags';
}

/**
* @return never
*/
public function setName($name) {
throw new Forbidden('Permission denied to rename this collection');
}

/**
* Returns the last modification time, as a unix timestamp
*
* @return int
* @return null
*/
public function getLastModified() {
return null;
Expand Down
22 changes: 21 additions & 1 deletion apps/dav/lib/SystemTag/SystemTagsObjectMappingCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public function __construct(
$this->user = $user;
}

/**
* @return void
*/
public function createFile($name, $data = null) {
$tagId = $name;
try {
Expand All @@ -110,10 +113,16 @@ public function createFile($name, $data = null) {
}
}

/**
* @return never
*/
public function createDirectory($name) {
throw new Forbidden('Permission denied to create collections');
}

/**
* @return SystemTagMappingNode
*/
public function getChild($tagName) {
try {
if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagName, true)) {
Expand All @@ -131,6 +140,11 @@ public function getChild($tagName) {
}
}

/**
* @return SystemTagMappingNode[]
*
* @psalm-return list<SystemTagMappingNode>
*/
public function getChildren() {
$tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType));
if (empty($tagIds)) {
Expand Down Expand Up @@ -168,6 +182,9 @@ public function childExists($tagId) {
}
}

/**
* @return never
*/
public function delete() {
throw new Forbidden('Permission denied to delete this collection');
}
Expand All @@ -176,14 +193,17 @@ public function getName() {
return $this->objectId;
}

/**
* @return never
*/
public function setName($name) {
throw new Forbidden('Permission denied to rename this collection');
}

/**
* Returns the last modification time, as a unix timestamp
*
* @return int
* @return null
*/
public function getLastModified() {
return null;
Expand Down
Loading

0 comments on commit 287da61

Please sign in to comment.