Skip to content

Commit

Permalink
fix(dav): add activity logging for favorites in dav
Browse files Browse the repository at this point in the history
Signed-off-by: grnd-alt <salimbelakkaf@outlook.de>
  • Loading branch information
grnd-alt committed Oct 28, 2024
1 parent 74cd6e2 commit e96dc20
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 53 deletions.
2 changes: 1 addition & 1 deletion apps/dav/lib/Connector/Sabre/ServerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public function createServer(string $baseUri,
));

if ($this->userSession->isLoggedIn()) {
$server->addPlugin(new TagsPlugin($objectTree, $this->tagManager));
$server->addPlugin(new TagsPlugin($objectTree, $this->tagManager, $this->eventDispatcher, $this->userSession));
$server->addPlugin(new SharesPlugin(
$objectTree,
$this->userSession,
Expand Down
10 changes: 9 additions & 1 deletion apps/dav/lib/Connector/Sabre/TagsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\NodeAddedToFavorite;
use OCP\Files\Events\NodeRemovedFromFavorite;
use OCP\ITagManager;
use OCP\ITags;
use OCP\IUserSession;
use Sabre\DAV\PropFind;
use Sabre\DAV\PropPatch;

Expand Down Expand Up @@ -67,6 +71,8 @@ class TagsPlugin extends \Sabre\DAV\ServerPlugin {
public function __construct(
private \Sabre\DAV\Tree $tree,
private ITagManager $tagManager,
private IEventDispatcher $eventDispatcher,
private IUserSession $userSession,
) {
$this->tagger = null;
$this->cachedTags = [];
Expand Down Expand Up @@ -251,11 +257,13 @@ public function handleUpdateProperties($path, PropPatch $propPatch) {
return true;
});

$propPatch->handle(self::FAVORITE_PROPERTYNAME, function ($favState) use ($node) {
$propPatch->handle(self::FAVORITE_PROPERTYNAME, function ($favState) use ($node, $path) {
if ((int)$favState === 1 || $favState === 'true') {
$this->getTagger()->tagAs($node->getId(), self::TAG_FAVORITE);
$this->eventDispatcher->dispatchTyped(new NodeAddedToFavorite($this->userSession->getUser(), $node->getId(), $path));
} else {
$this->getTagger()->unTag($node->getId(), self::TAG_FAVORITE);
$this->eventDispatcher->dispatchTyped(new NodeRemovedFromFavorite($this->userSession->getUser(), $node->getId(), $path));
}

if (is_null($favState)) {
Expand Down
2 changes: 1 addition & 1 deletion apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public function __construct(
}
$this->server->addPlugin(
new TagsPlugin(
$this->server->tree, \OC::$server->getTagManager()
$this->server->tree, \OC::$server->getTagManager(), \OC::$server->get(IEventDispatcher::class), \OC::$server->get(IUserSession::class)
)
);

Expand Down
28 changes: 27 additions & 1 deletion apps/dav/tests/unit/Connector/Sabre/TagsPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
use OCA\DAV\Connector\Sabre\TagList;
use OCA\DAV\Connector\Sabre\TagsPlugin;
use OCA\DAV\Upload\UploadFile;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\ITagManager;
use OCP\ITags;
use OCP\IUser;
use OCP\IUserSession;
use Sabre\DAV\Tree;

class TagsPluginTest extends \Test\TestCase {
Expand Down Expand Up @@ -42,6 +45,16 @@ class TagsPluginTest extends \Test\TestCase {
*/
private $tagger;

/**
* @var IEventDispatcher
*/
private $eventDispatcher;

/**
* @var IUserSession
*/
private $userSession;

/**
* @var TagsPlugin
*/
Expand All @@ -59,11 +72,24 @@ protected function setUp(): void {
$this->tagManager = $this->getMockBuilder(ITagManager::class)
->disableOriginalConstructor()
->getMock();

$this->eventDispatcher = $this->getMockBuilder(IEventDispatcher::class)
->disableOriginalConstructor()
->getMock();
$user = $this->createMock(IUser::class);
/**
* @var IUserSession
*/
$this->userSession = $this->createMock(IUserSession::class);
$this->userSession->expects($this->any())
->method('getUser')
->withAnyParameters()
->willReturn($user);
$this->tagManager->expects($this->any())
->method('load')
->with('files')
->willReturn($this->tagger);
$this->plugin = new TagsPlugin($this->tree, $this->tagManager);
$this->plugin = new TagsPlugin($this->tree, $this->tagManager, $this->eventDispatcher, $this->userSession);
$this->plugin->initialize($this->server);
}

Expand Down
2 changes: 2 additions & 0 deletions apps/files/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
'OCA\\Files\\Listener\\DeclarativeSettingsSetValueEventListener' => $baseDir . '/../lib/Listener/DeclarativeSettingsSetValueEventListener.php',
'OCA\\Files\\Listener\\LoadSearchPluginsListener' => $baseDir . '/../lib/Listener/LoadSearchPluginsListener.php',
'OCA\\Files\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files\\Listener\\NodeAddedToFavoriteListener' => $baseDir . '/../lib/Listener/NodeAddedToFavoriteListener.php',
'OCA\\Files\\Listener\\NodeRemovedFromFavoriteListener' => $baseDir . '/../lib/Listener/NodeRemovedFromFavoriteListener.php',
'OCA\\Files\\Listener\\RenderReferenceEventListener' => $baseDir . '/../lib/Listener/RenderReferenceEventListener.php',
'OCA\\Files\\Listener\\SyncLivePhotosListener' => $baseDir . '/../lib/Listener/SyncLivePhotosListener.php',
'OCA\\Files\\Migration\\Version11301Date20191205150729' => $baseDir . '/../lib/Migration/Version11301Date20191205150729.php',
Expand Down
2 changes: 2 additions & 0 deletions apps/files/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class ComposerStaticInitFiles
'OCA\\Files\\Listener\\DeclarativeSettingsSetValueEventListener' => __DIR__ . '/..' . '/../lib/Listener/DeclarativeSettingsSetValueEventListener.php',
'OCA\\Files\\Listener\\LoadSearchPluginsListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSearchPluginsListener.php',
'OCA\\Files\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files\\Listener\\NodeAddedToFavoriteListener' => __DIR__ . '/..' . '/../lib/Listener/NodeAddedToFavoriteListener.php',
'OCA\\Files\\Listener\\NodeRemovedFromFavoriteListener' => __DIR__ . '/..' . '/../lib/Listener/NodeRemovedFromFavoriteListener.php',
'OCA\\Files\\Listener\\RenderReferenceEventListener' => __DIR__ . '/..' . '/../lib/Listener/RenderReferenceEventListener.php',
'OCA\\Files\\Listener\\SyncLivePhotosListener' => __DIR__ . '/..' . '/../lib/Listener/SyncLivePhotosListener.php',
'OCA\\Files\\Migration\\Version11301Date20191205150729' => __DIR__ . '/..' . '/../lib/Migration/Version11301Date20191205150729.php',
Expand Down
7 changes: 6 additions & 1 deletion apps/files/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
use OCA\Files\Listener\DeclarativeSettingsSetValueEventListener;
use OCA\Files\Listener\LoadSearchPluginsListener;
use OCA\Files\Listener\LoadSidebarListener;
use OCA\Files\Listener\NodeAddedToFavoriteListener;
use OCA\Files\Listener\NodeRemovedFromFavoriteListener;
use OCA\Files\Listener\RenderReferenceEventListener;
use OCA\Files\Listener\SyncLivePhotosListener;
use OCA\Files\Notification\Notifier;
Expand All @@ -41,6 +43,8 @@
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\NodeAddedToFavorite;
use OCP\Files\Events\NodeRemovedFromFavorite;
use OCP\Files\IRootFolder;
use OCP\IConfig;
use OCP\IL10N;
Expand Down Expand Up @@ -122,7 +126,8 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(DeclarativeSettingsRegisterFormEvent::class, DeclarativeSettingsRegisterFormEventListener::class);
$context->registerEventListener(DeclarativeSettingsGetValueEvent::class, DeclarativeSettingsGetValueEventListener::class);
$context->registerEventListener(DeclarativeSettingsSetValueEvent::class, DeclarativeSettingsSetValueEventListener::class);

$context->registerEventListener(NodeAddedToFavorite::class, NodeAddedToFavoriteListener::class);
$context->registerEventListener(NodeRemovedFromFavorite::class, NodeRemovedFromFavoriteListener::class);
$context->registerSearchProvider(FilesSearchProvider::class);

$context->registerNotifierService(Notifier::class);
Expand Down
43 changes: 43 additions & 0 deletions apps/files/lib/Listener/NodeAddedToFavoriteListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Files\Listener;

use OCA\Files\Activity\FavoriteProvider;
use OCP\Activity\IManager as IActivityManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\NodeAddedToFavorite;

/** @template-implements IEventListener<NodeAddedToFavorite> */
class NodeAddedToFavoriteListener implements IEventListener {
public function __construct(
private IActivityManager $activityManager,
) {
}
public function handle(Event $event):void {
if (!($event instanceof NodeAddedToFavorite)) {
return;
}
$activityEvent = $this->activityManager->generateEvent();
try {
$activityEvent->setApp('files')
->setObject('files', $event->getFileId(), $event->getPath())
->setType('favorite')
->setAuthor($event->getUser()->getUID())
->setAffectedUser($event->getUser()->getUID())
->setTimestamp(time())
->setSubject(
FavoriteProvider::SUBJECT_ADDED,
['id' => $event->getFileId(), 'path' => $event->getPath()]
);
$this->activityManager->publish($activityEvent);
} catch (\InvalidArgumentException $e) {
} catch (\BadMethodCallException $e) {
}
}
}
43 changes: 43 additions & 0 deletions apps/files/lib/Listener/NodeRemovedFromFavoriteListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Files\Listener;

use OCA\Files\Activity\FavoriteProvider;
use OCP\Activity\IManager as IActivityManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\NodeRemovedFromFavorite;

/** @template-implements IEventListener<NodeRemovedFromFavorite> */
class NodeRemovedFromFavoriteListener implements IEventListener {
public function __construct(
private IActivityManager $activityManager,
) {
}
public function handle(Event $event):void {
if (!($event instanceof NodeRemovedFromFavorite)) {
return;
}
$activityEvent = $this->activityManager->generateEvent();
try {
$activityEvent->setApp('files')
->setObject('files', $event->getFileId(), $event->getPath())
->setType('favorite')
->setAuthor($event->getUser()->getUID())
->setAffectedUser($event->getUser()->getUID())
->setTimestamp(time())
->setSubject(
FavoriteProvider::SUBJECT_REMOVED,
['id' => $event->getFileId(), 'path' => $event->getPath()]
);
$this->activityManager->publish($activityEvent);
} catch (\InvalidArgumentException $e) {
} catch (\BadMethodCallException $e) {
}
}
}
42 changes: 2 additions & 40 deletions apps/files/lib/Service/TagService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
*/
namespace OCA\Files\Service;

use OCA\Files\Activity\FavoriteProvider;
use OCP\Activity\IManager;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\NodeAddedToFavorite;
use OCP\Files\Events\NodeRemovedFromFavorite;
use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\ITags;
use OCP\IUser;
use OCP\IUserSession;

/**
Expand Down Expand Up @@ -61,14 +59,14 @@ public function updateFileTags($path, $tags) {
$newTags = array_diff($tags, $currentTags);
foreach ($newTags as $tag) {
if ($tag === ITags::TAG_FAVORITE) {
$this->addActivity(true, $fileId, $path);
$this->dispatcher->dispatchTyped(new NodeAddedToFavorite($this->userSession->getUser(), $fileId, $path));
}
$this->tagger->tagAs($fileId, $tag);
}
$deletedTags = array_diff($currentTags, $tags);
foreach ($deletedTags as $tag) {
if ($tag === ITags::TAG_FAVORITE) {
$this->addActivity(false, $fileId, $path);
$this->dispatcher->dispatchTyped(new NodeRemovedFromFavorite($this->userSession->getUser(), $fileId, $path));
}
$this->tagger->unTag($fileId, $tag);
}
Expand All @@ -77,40 +75,4 @@ public function updateFileTags($path, $tags) {
// list is up to date, in case of concurrent changes ?
return $tags;
}

/**
* @param bool $addToFavorite
* @param int $fileId
* @param string $path
*/
protected function addActivity($addToFavorite, $fileId, $path) {
$user = $this->userSession->getUser();
if (!$user instanceof IUser) {
return;
}

if ($addToFavorite) {
$event = new NodeAddedToFavorite($user, $fileId, $path);
} else {
$event = new NodeRemovedFromFavorite($user, $fileId, $path);
}
$this->dispatcher->dispatchTyped($event);

$event = $this->activityManager->generateEvent();
try {
$event->setApp('files')
->setObject('files', $fileId, $path)
->setType('favorite')
->setAuthor($user->getUID())
->setAffectedUser($user->getUID())
->setTimestamp(time())
->setSubject(
$addToFavorite ? FavoriteProvider::SUBJECT_ADDED : FavoriteProvider::SUBJECT_REMOVED,
['id' => $fileId, 'path' => $path]
);
$this->activityManager->publish($event);
} catch (\InvalidArgumentException $e) {
} catch (\BadMethodCallException $e) {
}
}
}
27 changes: 19 additions & 8 deletions apps/files/tests/Service/TagServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use OCA\Files\Service\TagService;
use OCP\Activity\IManager;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\NodeAddedToFavorite;
use OCP\Files\Events\NodeRemovedFromFavorite;
use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\ITags;
Expand Down Expand Up @@ -107,8 +109,8 @@ public function testUpdateFileTags(): void {
$tag1 = 'tag1';
$tag2 = 'tag2';

$this->tagService->expects($this->never())
->method('addActivity');
$this->dispatcher->expects($this->never())
->method('dispatchTyped');

$subdir = $this->root->newFolder('subdir');
$testFile = $subdir->newFile('test.txt');
Expand Down Expand Up @@ -148,12 +150,21 @@ public function testFavoriteActivity(): void {
$subdir = $this->root->newFolder('subdir');
$file = $subdir->newFile('test.txt');

$this->tagService->expects($this->exactly(2))
->method('addActivity')
->withConsecutive(
[true, $file->getId(), 'subdir/test.txt'],
[false, $file->getId(), 'subdir/test.txt']
);
$invokedCount = $this->exactly(2);

$this->dispatcher->expects($invokedCount)
->method('dispatchTyped')
->willReturnCallback(function ($event) use ($invokedCount, $file) {
if ($invokedCount->getInvocationCount() === 1) {
$this->assertInstanceOf(NodeAddedToFavorite::class, $event);
}
if ($invokedCount->getInvocationCount() === 2) {
$this->assertInstanceOf(NodeRemovedFromFavorite::class, $event);
}
$this->assertEquals($this->userSession->getUser()->getUID(), $event->getUser()->getUID());
$this->assertEquals('subdir/test.txt', $event->getPath());
$this->assertEquals($file->getId(), $event->getFileId());
});

// set tags
$this->tagService->updateFileTags('subdir/test.txt', [ITags::TAG_FAVORITE]);
Expand Down

0 comments on commit e96dc20

Please sign in to comment.