Skip to content

Commit 03b51ed

Browse files
committed
feat(admin_audit): add stable operation identifier to audit log entries
Every audit log entry now carries a machine-readable "operation" field (e.g. "files.file.read") in its data, next to the human-readable message. Log consumers can filter on it instead of matching message text, which may change between releases. The names are defined once in the new OCA\AdminAudit\Operation enum. Operations passed by other apps through CriticalActionPerformedEvent are written as given. Refs nextcloud-gmbh/governance#199 Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
1 parent b54ee0f commit 03b51ed

36 files changed

Lines changed: 1063 additions & 26 deletions

‎apps/admin_audit/composer/composer/autoload_classmap.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@
2727
'OCA\\AdminAudit\\Listener\\SharingEventListener' => $baseDir . '/../lib/Listener/SharingEventListener.php',
2828
'OCA\\AdminAudit\\Listener\\TagEventListener' => $baseDir . '/../lib/Listener/TagEventListener.php',
2929
'OCA\\AdminAudit\\Listener\\UserManagementEventListener' => $baseDir . '/../lib/Listener/UserManagementEventListener.php',
30+
'OCA\\AdminAudit\\Operation' => $baseDir . '/../lib/Operation.php',
3031
);

‎apps/admin_audit/composer/composer/autoload_static.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ComposerStaticInitAdminAudit
4242
'OCA\\AdminAudit\\Listener\\SharingEventListener' => __DIR__ . '/..' . '/../lib/Listener/SharingEventListener.php',
4343
'OCA\\AdminAudit\\Listener\\TagEventListener' => __DIR__ . '/..' . '/../lib/Listener/TagEventListener.php',
4444
'OCA\\AdminAudit\\Listener\\UserManagementEventListener' => __DIR__ . '/..' . '/../lib/Listener/UserManagementEventListener.php',
45+
'OCA\\AdminAudit\\Operation' => __DIR__ . '/..' . '/../lib/Operation.php',
4546
);
4647

4748
public static function getInitializer(ClassLoader $loader)

‎apps/admin_audit/lib/Actions/Action.php‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace OCA\AdminAudit\Actions;
1010

1111
use OCA\AdminAudit\IAuditLogger;
12+
use OCA\AdminAudit\Operation;
1213

1314
class Action {
1415

@@ -20,21 +21,28 @@ public function __construct(
2021
/**
2122
* Log a single action with a log level of info
2223
*
24+
* @param Operation|string|null $operation Stable identifier of the action. A string in the form `app.entity.action` is only expected from other apps via CriticalActionPerformedEvent
2325
* @param string $text
2426
* @param array<string, scalar|null|\DateTimeInterface> $params
2527
* @param list<string> $elements
2628
* @param bool $obfuscateParameters
2729
*/
2830
public function log(
31+
Operation|string|null $operation,
2932
string $text,
3033
array $params,
3134
array $elements,
3235
bool $obfuscateParameters = false,
3336
): void {
37+
$baseContext = ['app' => 'admin_audit'];
38+
if ($operation !== null) {
39+
$baseContext['operation'] = $operation instanceof Operation ? $operation->value : $operation;
40+
}
41+
3442
foreach ($elements as $element) {
3543
if (!array_key_exists($element, $params)) {
3644
$message = '$params["' . $element . '"] was missing.';
37-
$context = ['app' => 'admin_audit'];
45+
$context = $baseContext;
3846

3947
if (!$obfuscateParameters) {
4048
$message .= ' Transferred value: {params}';
@@ -47,7 +55,7 @@ public function log(
4755
}
4856

4957
$replaceArray = [];
50-
$context = ['app' => 'admin_audit'];
58+
$context = $baseContext;
5159
foreach ($elements as $element) {
5260
$value = $params[$element];
5361
if ($value instanceof \DateTimeInterface) {

‎apps/admin_audit/lib/Actions/Files.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace OCA\AdminAudit\Actions;
1010

1111
use OC\Files\Node\NonExistingFile;
12+
use OCA\AdminAudit\Operation;
1213
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
1314
use OCP\Files\Events\Node\BeforeNodeReadEvent;
1415
use OCP\Files\Events\Node\NodeCopiedEvent;
@@ -43,6 +44,7 @@ public function read(BeforeNodeReadEvent $event): void {
4344
return;
4445
}
4546
$this->log(
47+
Operation::FileRead,
4648
'File with id "%s" accessed: "%s"',
4749
$params,
4850
array_keys($params)
@@ -69,6 +71,7 @@ public function afterRename(NodeRenamedEvent $event): void {
6971
}
7072

7173
$this->log(
74+
Operation::FileRenamed,
7275
'File renamed with id "%s" from "%s" to "%s"',
7376
$params,
7477
array_keys($params)
@@ -95,6 +98,7 @@ public function create(NodeCreatedEvent $event): void {
9598
return;
9699
}
97100
$this->log(
101+
Operation::FileCreated,
98102
'File with id "%s" created: "%s"',
99103
$params,
100104
array_keys($params)
@@ -121,6 +125,7 @@ public function copy(NodeCopiedEvent $event): void {
121125
return;
122126
}
123127
$this->log(
128+
Operation::FileCopied,
124129
'File id copied from: "%s" to "%s", path from "%s" to "%s"',
125130
$params,
126131
array_keys($params)
@@ -148,6 +153,7 @@ public function write(NodeWrittenEvent $event): void {
148153
}
149154

150155
$this->log(
156+
Operation::FileWritten,
151157
'File with id "%s" written to: "%s"',
152158
$params,
153159
array_keys($params)
@@ -171,6 +177,7 @@ public function delete(BeforeNodeDeletedEvent $event): void {
171177
return;
172178
}
173179
$this->log(
180+
Operation::FileDeleted,
174181
'File with id "%s" deleted: "%s"',
175182
$params,
176183
array_keys($params)

‎apps/admin_audit/lib/Actions/Sharing.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace OCA\AdminAudit\Actions;
1010

11+
use OCA\AdminAudit\Operation;
12+
1113
/**
1214
* Class Sharing logs the sharing actions
1315
*
@@ -22,6 +24,7 @@ class Sharing extends Action {
2224
*/
2325
public function updatePermissions(array $params): void {
2426
$this->log(
27+
Operation::SharePermissionsUpdated,
2528
'The permissions of the shared %s "%s" with ID "%s" have been changed to "%s"',
2629
$params,
2730
[
@@ -40,6 +43,7 @@ public function updatePermissions(array $params): void {
4043
*/
4144
public function updatePassword(array $params): void {
4245
$this->log(
46+
Operation::SharePasswordUpdated,
4347
'The password of the publicly shared %s "%s" with ID "%s" has been changed',
4448
$params,
4549
[
@@ -58,6 +62,7 @@ public function updatePassword(array $params): void {
5862
public function updateExpirationDate(array $params): void {
5963
if ($params['date'] === null) {
6064
$this->log(
65+
Operation::ShareExpirationRemoved,
6166
'The expiration date of the publicly shared %s with ID "%s" has been removed',
6267
$params,
6368
[
@@ -67,6 +72,7 @@ public function updateExpirationDate(array $params): void {
6772
);
6873
} else {
6974
$this->log(
75+
Operation::ShareExpirationUpdated,
7076
'The expiration date of the publicly shared %s with ID "%s" has been changed to "%s"',
7177
$params,
7278
[
@@ -85,6 +91,7 @@ public function updateExpirationDate(array $params): void {
8591
*/
8692
public function shareAccessed(array $params): void {
8793
$this->log(
94+
Operation::ShareLinkAccessed,
8895
'The shared %s with the token "%s" by "%s" has been accessed.',
8996
$params,
9097
[

‎apps/admin_audit/lib/Actions/Trashbin.php‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88

99
namespace OCA\AdminAudit\Actions;
1010

11+
use OCA\AdminAudit\Operation;
12+
1113
class Trashbin extends Action {
1214
public function delete(array $params): void {
13-
$this->log('File "%s" deleted from trash bin.',
15+
$this->log(Operation::TrashbinFileDeleted, 'File "%s" deleted from trash bin.',
1416
['path' => $params['path']], ['path']
1517
);
1618
}
1719

1820
public function restore(array $params): void {
19-
$this->log('File "%s" restored from trash bin.',
21+
$this->log(Operation::TrashbinFileRestored, 'File "%s" restored from trash bin.',
2022
['path' => $params['filePath']], ['path']
2123
);
2224
}

‎apps/admin_audit/lib/Actions/Versions.php‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88

99
namespace OCA\AdminAudit\Actions;
1010

11+
use OCA\AdminAudit\Operation;
12+
1113
class Versions extends Action {
1214
public function delete(array $params): void {
13-
$this->log('Version "%s" was deleted.',
15+
$this->log(Operation::VersionDeleted, 'Version "%s" was deleted.',
1416
['path' => $params['path']],
1517
['path']
1618
);

‎apps/admin_audit/lib/Listener/AppManagementEventListener.php‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace OCA\AdminAudit\Listener;
1111

1212
use OCA\AdminAudit\Actions\Action;
13+
use OCA\AdminAudit\Operation;
1314
use OCP\App\Events\AppDisableEvent;
1415
use OCP\App\Events\AppEnableEvent;
1516
use OCP\App\Events\AppUpdateEvent;
@@ -33,27 +34,27 @@ public function handle(Event $event): void {
3334

3435
private function appEnable(AppEnableEvent $event): void {
3536
if (empty($event->getGroupIds())) {
36-
$this->log('App "%s" enabled',
37+
$this->log(Operation::AppEnabled, 'App "%s" enabled',
3738
['app' => $event->getAppId()],
3839
['app']
3940
);
4041
} else {
41-
$this->log('App "%1$s" enabled for groups: %2$s',
42+
$this->log(Operation::AppEnabled, 'App "%1$s" enabled for groups: %2$s',
4243
['app' => $event->getAppId(), 'groups' => implode(', ', $event->getGroupIds())],
4344
['app', 'groups']
4445
);
4546
}
4647
}
4748

4849
private function appDisable(AppDisableEvent $event): void {
49-
$this->log('App "%s" disabled',
50+
$this->log(Operation::AppDisabled, 'App "%s" disabled',
5051
['app' => $event->getAppId()],
5152
['app']
5253
);
5354
}
5455

5556
private function appUpdate(AppUpdateEvent $event): void {
56-
$this->log('App "%s" updated',
57+
$this->log(Operation::AppUpdated, 'App "%s" updated',
5758
['app' => $event->getAppId()],
5859
['app']
5960
);

‎apps/admin_audit/lib/Listener/AuthEventListener.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace OCA\AdminAudit\Listener;
1111

1212
use OCA\AdminAudit\Actions\Action;
13+
use OCA\AdminAudit\Operation;
1314
use OCP\Authentication\Events\AnyLoginFailedEvent;
1415
use OCP\EventDispatcher\Event;
1516
use OCP\EventDispatcher\IEventListener;
@@ -37,6 +38,7 @@ public function handle(Event $event): void {
3738

3839
private function beforeUserLoggedIn(BeforeUserLoggedInEvent $event): void {
3940
$this->log(
41+
Operation::LoginAttempted,
4042
'Login attempt: "%s"',
4143
[
4244
'uid' => $event->getUsername()
@@ -50,6 +52,7 @@ private function beforeUserLoggedIn(BeforeUserLoggedInEvent $event): void {
5052

5153
private function userLoggedIn(UserLoggedInWithCookieEvent|UserLoggedInEvent $event): void {
5254
$this->log(
55+
Operation::LoginSucceeded,
5356
'Login successful: "%s"',
5457
[
5558
'uid' => $event->getUser()->getUID()
@@ -63,6 +66,7 @@ private function userLoggedIn(UserLoggedInWithCookieEvent|UserLoggedInEvent $eve
6366

6467
private function beforeUserLogout(BeforeUserLoggedOutEvent $event): void {
6568
$this->log(
69+
Operation::LogoutPerformed,
6670
'Logout occurred',
6771
[],
6872
[]
@@ -71,6 +75,7 @@ private function beforeUserLogout(BeforeUserLoggedOutEvent $event): void {
7175

7276
private function anyLoginFailed(AnyLoginFailedEvent $event): void {
7377
$this->log(
78+
Operation::LoginFailed,
7479
'Login failed: "%s"',
7580
[
7681
'loginName' => $event->getLoginName()

‎apps/admin_audit/lib/Listener/CacheEventListener.php‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace OCA\AdminAudit\Listener;
1111

1212
use OCA\AdminAudit\Actions\Action;
13+
use OCA\AdminAudit\Operation;
1314
use OCP\EventDispatcher\Event;
1415
use OCP\EventDispatcher\IEventListener;
1516
use OCP\Files\Cache\CacheEntryInsertedEvent;
@@ -29,7 +30,7 @@ public function handle(Event $event): void {
2930
}
3031

3132
private function entryInserted(CacheEntryInsertedEvent $event): void {
32-
$this->log('Cache entry inserted for fileid "%1$d", path "%2$s" on storageid "%3$d"',
33+
$this->log(Operation::CacheEntryInserted, 'Cache entry inserted for fileid "%1$d", path "%2$s" on storageid "%3$d"',
3334
[
3435
'fileid' => $event->getFileId(),
3536
'path' => $event->getPath(),
@@ -40,7 +41,7 @@ private function entryInserted(CacheEntryInsertedEvent $event): void {
4041
}
4142

4243
private function entryRemoved(CacheEntryRemovedEvent $event): void {
43-
$this->log('Cache entry removed for fileid "%1$d", path "%2$s" on storageid "%3$d"',
44+
$this->log(Operation::CacheEntryRemoved, 'Cache entry removed for fileid "%1$d", path "%2$s" on storageid "%3$d"',
4445
[
4546
'fileid' => $event->getFileId(),
4647
'path' => $event->getPath(),

0 commit comments

Comments
 (0)