mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
fix(dav): add activity logging for favorites in dav
Signed-off-by: grnd-alt <salimbelakkaf@outlook.de>
This commit is contained in:
parent
5ee4c9effa
commit
2d02d83597
11 changed files with 155 additions and 53 deletions
|
|
@ -136,7 +136,7 @@ class ServerFactory {
|
|||
));
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,12 @@ namespace OCA\DAV\Connector\Sabre;
|
|||
* 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;
|
||||
|
||||
|
|
@ -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 = [];
|
||||
|
|
@ -251,11 +257,13 @@ class TagsPlugin extends \Sabre\DAV\ServerPlugin {
|
|||
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)) {
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ class Server {
|
|||
}
|
||||
$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)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@ use OCA\DAV\Connector\Sabre\Node;
|
|||
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 {
|
||||
|
|
@ -42,6 +45,16 @@ class TagsPluginTest extends \Test\TestCase {
|
|||
*/
|
||||
private $tagger;
|
||||
|
||||
/**
|
||||
* @var IEventDispatcher
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @var IUserSession
|
||||
*/
|
||||
private $userSession;
|
||||
|
||||
/**
|
||||
* @var TagsPlugin
|
||||
*/
|
||||
|
|
@ -59,11 +72,24 @@ class TagsPluginTest extends \Test\TestCase {
|
|||
$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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ return array(
|
|||
'OCA\\Files\\Helper' => $baseDir . '/../lib/Helper.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',
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ class ComposerStaticInitFiles
|
|||
'OCA\\Files\\Helper' => __DIR__ . '/..' . '/../lib/Helper.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',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ use OCA\Files\Event\LoadSearchPlugins;
|
|||
use OCA\Files\Event\LoadSidebar;
|
||||
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;
|
||||
|
|
@ -39,6 +41,8 @@ use OCP\Files\Events\Node\BeforeNodeCopiedEvent;
|
|||
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;
|
||||
|
|
@ -116,7 +120,8 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(BeforeNodeCopiedEvent::class, SyncLivePhotosListener::class);
|
||||
$context->registerEventListener(NodeCopiedEvent::class, SyncLivePhotosListener::class);
|
||||
$context->registerEventListener(LoadSearchPlugins::class, LoadSearchPluginsListener::class);
|
||||
|
||||
$context->registerEventListener(NodeAddedToFavorite::class, NodeAddedToFavoriteListener::class);
|
||||
$context->registerEventListener(NodeRemovedFromFavorite::class, NodeRemovedFromFavoriteListener::class);
|
||||
$context->registerSearchProvider(FilesSearchProvider::class);
|
||||
|
||||
$context->registerNotifierService(Notifier::class);
|
||||
|
|
|
|||
43
apps/files/lib/Listener/NodeAddedToFavoriteListener.php
Normal file
43
apps/files/lib/Listener/NodeAddedToFavoriteListener.php
Normal file
|
|
@ -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
apps/files/lib/Listener/NodeRemovedFromFavoriteListener.php
Normal file
43
apps/files/lib/Listener/NodeRemovedFromFavoriteListener.php
Normal file
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
namespace OCA\Files\Service;
|
||||
|
||||
use OCA\Files\Activity\FavoriteProvider;
|
||||
use OCP\Activity\IManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Events\NodeAddedToFavorite;
|
||||
|
|
@ -15,7 +14,6 @@ use OCP\Files\Events\NodeRemovedFromFavorite;
|
|||
use OCP\Files\Folder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\ITags;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
|
||||
/**
|
||||
|
|
@ -61,14 +59,14 @@ class TagService {
|
|||
$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);
|
||||
}
|
||||
|
|
@ -77,40 +75,4 @@ class TagService {
|
|||
// 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ namespace OCA\Files\Tests\Service;
|
|||
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;
|
||||
|
|
@ -107,8 +109,8 @@ class TagServiceTest extends \Test\TestCase {
|
|||
$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');
|
||||
|
|
@ -148,12 +150,21 @@ class TagServiceTest extends \Test\TestCase {
|
|||
$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]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue