Merge pull request #44871 from nextcloud/feature/include-file-id-in-audit-logs

feat: include file id in audit logs
pull/45122/head
yemkareems 7 months ago committed by GitHub
commit 66aad438ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 202
      apps/admin_audit/lib/Actions/Files.php
  2. 93
      apps/admin_audit/lib/AppInfo/Application.php

@ -27,6 +27,18 @@ declare(strict_types=1);
*/
namespace OCA\AdminAudit\Actions;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Preview\BeforePreviewFetchedEvent;
use Psr\Log\LoggerInterface;
/**
* Class Files logs the actions to files
*
@ -36,134 +48,210 @@ class Files extends Action {
/**
* Logs file read actions
*
* @param array $params
* @param BeforeNodeReadEvent $event
*/
public function read(array $params): void {
public function read(BeforeNodeReadEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file read: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File accessed: "%s"',
'File with id "%s" accessed: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs rename actions of files
*
* @param array $params
* @param NodeRenamedEvent $event
*/
public function rename(array $params): void {
public function rename(NodeRenamedEvent $event): void {
try {
$source = $event->getSource();
$target = $event->getTarget();
$params = [
'newid' => $target->getId(),
'oldpath' => mb_substr($source->getPath(), 5),
'newpath' => mb_substr($target->getPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file rename: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File renamed: "%s" to "%s"',
'File renamed with id "%s" from "%s" to "%s"',
$params,
[
'oldpath',
'newpath',
]
array_keys($params)
);
}
/**
* Logs creation of files
*
* @param array $params
* @param NodeCreatedEvent $event
*/
public function create(array $params): void {
if ($params['path'] === '/' || $params['path'] === '' || $params['path'] === null) {
public function create(NodeCreatedEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file create: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
if ($params['path'] === '/' || $params['path'] === '') {
return;
}
$this->log(
'File created: "%s"',
'File with id "%s" created: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs copying of files
*
* @param array $params
* @param NodeCopiedEvent $event
*/
public function copy(array $params): void {
public function copy(NodeCopiedEvent $event): void {
try {
$params = [
'oldid' => $event->getSource()->getId(),
'newid' => $event->getTarget()->getId(),
'oldpath' => mb_substr($event->getSource()->getInternalPath(), 5),
'newpath' => mb_substr($event->getTarget()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file copy: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File copied: "%s" to "%s"',
'File id copied from: "%s" to "%s", path from "%s" to "%s"',
$params,
[
'oldpath',
'newpath',
]
array_keys($params)
);
}
/**
* Logs writing of files
*
* @param array $params
* @param BeforeNodeWrittenEvent $event
*/
public function write(array $params): void {
if ($params['path'] === '/' || $params['path'] === '' || $params['path'] === null) {
public function write(BeforeNodeWrittenEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file write: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
if ($params['path'] === '/' || $params['path'] === '') {
return;
}
$this->log(
'File written to: "%s"',
'File with id "%s" written to: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs update of files
*
* @param array $params
* @param NodeWrittenEvent $event
*/
public function update(array $params): void {
public function update(NodeWrittenEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file update: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File updated: "%s"',
'File with id "%s" updated: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs deletions of files
*
* @param array $params
* @param NodeDeletedEvent $event
*/
public function delete(array $params): void {
public function delete(NodeDeletedEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file delete: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File deleted: "%s"',
'File with id "%s" deleted: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs preview access to a file
*
* @param array $params
* @param BeforePreviewFetchedEvent $event
*/
public function preview(array $params): void {
public function preview(BeforePreviewFetchedEvent $event): void {
try {
$file = $event->getNode();
$params = [
'id' => $file->getId(),
'width' => $event->getWidth(),
'height' => $event->getHeight(),
'crop' => $event->isCrop(),
'mode' => $event->getMode(),
'path' => mb_substr($file->getInternalPath(), 5)
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file preview: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'Preview accessed: "%s" (width: "%s", height: "%s" crop: "%s", mode: "%s")',
'Preview accessed: (id: "%s", width: "%s", height: "%s" crop: "%s", mode: "%s", path: "%s")',
$params,
[
'path',
'width',
'height',
'crop',
'mode'
]
array_keys($params)
);
}
}

@ -33,7 +33,6 @@ declare(strict_types=1);
*/
namespace OCA\AdminAudit\AppInfo;
use OC\Files\Filesystem;
use OC\Group\Manager as GroupManager;
use OC\User\Session as UserSession;
use OCA\AdminAudit\Actions\AppManagement;
@ -58,6 +57,13 @@ use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed;
use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengePassed;
use OCP\Console\ConsoleEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserSession;
@ -195,58 +201,57 @@ class Application extends App implements IBootstrap {
$eventDispatcher->addListener(
BeforePreviewFetchedEvent::class,
function (BeforePreviewFetchedEvent $event) use ($fileActions) {
$file = $event->getNode();
$fileActions->preview([
'path' => mb_substr($file->getInternalPath(), 5),
'width' => $event->getWidth(),
'height' => $event->getHeight(),
'crop' => $event->isCrop(),
'mode' => $event->getMode()
]);
$fileActions->preview($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_rename,
$fileActions,
'rename'
$eventDispatcher->addListener(
NodeRenamedEvent::class,
function (NodeRenamedEvent $event) use ($fileActions) {
$fileActions->rename($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_create,
$fileActions,
'create'
$eventDispatcher->addListener(
NodeCreatedEvent::class,
function (NodeCreatedEvent $event) use ($fileActions) {
$fileActions->create($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_copy,
$fileActions,
'copy'
$eventDispatcher->addListener(
NodeCopiedEvent::class,
function (NodeCopiedEvent $event) use ($fileActions) {
$fileActions->copy($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_write,
$fileActions,
'write'
$eventDispatcher->addListener(
BeforeNodeWrittenEvent::class,
function (BeforeNodeWrittenEvent $event) use ($fileActions) {
$fileActions->write($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_update,
$fileActions,
'update'
$eventDispatcher->addListener(
NodeWrittenEvent::class,
function (NodeWrittenEvent $event) use ($fileActions) {
$fileActions->update($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_read,
$fileActions,
'read'
$eventDispatcher->addListener(
BeforeNodeReadEvent::class,
function (BeforeNodeReadEvent $event) use ($fileActions) {
$fileActions->read($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_delete,
$fileActions,
'delete'
$eventDispatcher->addListener(
NodeDeletedEvent::class,
function (NodeDeletedEvent $event) use ($fileActions) {
$fileActions->delete($event);
}
);
}

Loading…
Cancel
Save