Skip to content

Commit 3e3e79f

Browse files
committed
t # This is a combination of 6 commits.
Dispatch audit event when changing ACL rules Signed-off-by: Carl Schwan <carl@carlschwan.eu>
1 parent ff38248 commit 3e3e79f

File tree

2 files changed

+112
-8
lines changed

2 files changed

+112
-8
lines changed

lib/ACL/RuleManager.php

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,20 @@
2626
use OCA\GroupFolders\ACL\UserMapping\IUserMapping;
2727
use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
2828
use OCP\DB\QueryBuilder\IQueryBuilder;
29+
use OCP\EventDispatcher\IEventDispatcher;
2930
use OCP\IDBConnection;
3031
use OCP\IUser;
32+
use OCP\Log\Audit\CriticalActionPerformedEvent;
3133

3234
class RuleManager {
33-
/** @var IDBConnection */
34-
private $connection;
35-
/** @var IUserMappingManager */
36-
private $userMappingManager;
35+
private IDBConnection $connection;
36+
private IUserMappingManager $userMappingManager;
37+
private IEventDispatcher $eventDispatcher;
3738

38-
public function __construct(IDBConnection $connection, IUserMappingManager $userMappingManager) {
39+
public function __construct(IDBConnection $connection, IUserMappingManager $userMappingManager, IEventDispatcher $eventDispatcher) {
3940
$this->connection = $connection;
4041
$this->userMappingManager = $userMappingManager;
42+
$this->eventDispatcher = $eventDispatcher;
4143
}
4244

4345
private function createRule(array $data): ?Rule {
@@ -293,6 +295,26 @@ public function saveRule(Rule $rule): void {
293295
->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter($rule->getUserMapping()->getType())))
294296
->andWhere($query->expr()->eq('mapping_id', $query->createNamedParameter($rule->getUserMapping()->getId())));
295297
$query->executeStatement();
298+
299+
if ($rule->getUserMapping()->getType() === 'user') {
300+
$logMessage = 'The ACL rule was updated to permission "%s" and mask "%s" for file/folder with id "%s" for user "%s"';
301+
$params = [
302+
'permissions' => $rule->getPermissions(),
303+
'mask' => $rule->getMask(),
304+
'fileId' => $rule->getFileId(),
305+
'user' => $rule->getUserMapping()->getDisplayName() . ' (' . $rule->getUserMapping()->getId() . ')',
306+
];
307+
} else {
308+
$logMessage = 'The ACL rule was updated to permission "%s" and mask "%s" for file/folder with id "%s" for group "%s"';
309+
$params = [
310+
'permissions' => $rule->getPermissions(),
311+
'mask' => $rule->getMask(),
312+
'fileId' => $rule->getFileId(),
313+
'user' => $rule->getUserMapping()->getDisplayName(),
314+
];
315+
}
316+
317+
$this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent($logMessage, $params));
296318
} else {
297319
$query = $this->connection->getQueryBuilder();
298320
$query->insert('group_folders_acl')
@@ -304,6 +326,26 @@ public function saveRule(Rule $rule): void {
304326
'permissions' => $query->createNamedParameter($rule->getPermissions(), IQueryBuilder::PARAM_INT)
305327
]);
306328
$query->executeStatement();
329+
330+
if ($rule->getUserMapping()->getType() === 'user') {
331+
$logMessage = 'A new ACL rule was created to permission "%s" and mask "%s" for file/folder with id "%s" for user "%s"';
332+
$params = [
333+
'permissions' => $rule->getPermissions(),
334+
'mask' => $rule->getMask(),
335+
'fileId' => $rule->getFileId(),
336+
'user' => $rule->getUserMapping()->getDisplayName() . ' (' . $rule->getUserMapping()->getId() . ')',
337+
];
338+
} else {
339+
$logMessage = 'A new ACL rule was created to permission "%s" and mask "%s" for file/folder with id "%s" for group "%s"';
340+
$params = [
341+
'permissions' => $rule->getPermissions(),
342+
'mask' => $rule->getMask(),
343+
'fileId' => $rule->getFileId(),
344+
'group' => $rule->getUserMapping()->getDisplayName(),
345+
];
346+
}
347+
348+
$this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent($logMessage, $params));
307349
}
308350
}
309351

@@ -314,5 +356,21 @@ public function deleteRule(Rule $rule): void {
314356
->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter($rule->getUserMapping()->getType())))
315357
->andWhere($query->expr()->eq('mapping_id', $query->createNamedParameter($rule->getUserMapping()->getId())));
316358
$query->executeStatement();
359+
360+
if ($rule->getUserMapping()->getType() === 'user') {
361+
$logMessage = 'The ACL rule was deleted for file/folder with id: "%s" for the user "%s"';
362+
$params = [
363+
'fileId' => $rule->getFileId(),
364+
'user' => $rule->getUserMapping()->getDisplayName() . ' (' . $rule->getUserMapping()->getId() . ')',
365+
];
366+
} else {
367+
$logMessage = 'The ACL rule was deleted for file/folder with id: "%s" for the group "%s"';
368+
$params = [
369+
'fileId' => $rule->getFileId(),
370+
'group' => $rule->getUserMapping()->getDisplayName(),
371+
];
372+
}
373+
374+
$this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent($logMessage, $params));
317375
}
318376
}

tests/ACL/RuleManagerTest.php

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
use OCA\GroupFolders\ACL\RuleManager;
2929
use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
3030
use OCA\GroupFolders\ACL\UserMapping\UserMapping;
31+
use OCP\EventDispatcher\IEventDispatcher;
32+
use OCP\Log\Audit\CriticalActionPerformedEvent;
3133
use OCP\IUser;
3234
use Test\TestCase;
3335

@@ -42,6 +44,9 @@ class RuleManagerTest extends TestCase {
4244
/** @var \PHPUnit_Framework_MockObject_MockObject | IUser */
4345
private $user;
4446

47+
/** @var \PHPUnit_Framework_MockObject_MockObject | IEventDispatcher */
48+
private $eventDispatcher;
49+
4550
protected function setUp(): void {
4651
parent::setUp();
4752

@@ -53,18 +58,51 @@ protected function setUp(): void {
5358
$this->userMappingManager->expects($this->any())
5459
->method('mappingFromId')
5560
->willReturnCallback(function ($type, $id) {
56-
return new UserMapping($type, $id);
61+
if ($type === 'user') {
62+
return new UserMapping($type, $id, 'The User');
63+
} else {
64+
return new UserMapping($type, $id);
65+
}
5766
});
58-
$this->ruleManager = new RuleManager(\OC::$server->getDatabaseConnection(), $this->userMappingManager);
67+
68+
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
69+
$this->ruleManager = new RuleManager(\OC::$server->getDatabaseConnection(), $this->userMappingManager, $this->eventDispatcher);
5970
}
6071

6172
public function testGetSetRule() {
62-
$mapping = new UserMapping('test', '1');
73+
$mapping = new UserMapping('user', '1', 'The User');
6374
$this->userMappingManager->expects($this->any())
6475
->method('getMappingsForUser')
6576
->with($this->user)
6677
->willReturn([$mapping]);
6778

79+
$this->eventDispatcher->expects($this->any())
80+
->method('dispatchTyped')
81+
->withConsecutive(
82+
[$this->callback(function(CriticalActionPerformedEvent $event): bool {
83+
return $event->getParameters() === [
84+
'permissions' => 0b00001001,
85+
'mask' => 0b00001111,
86+
'fileId' => 10,
87+
'user' => 'The User (1)',
88+
];
89+
})],
90+
[$this->callback(function(CriticalActionPerformedEvent $event): bool {
91+
return $event->getParameters() === [
92+
'permissions' => 0b00001000,
93+
'mask' => 0b00001111,
94+
'fileId' => 10,
95+
'user' => 'The User (1)',
96+
];
97+
})],
98+
[$this->callback(function(CriticalActionPerformedEvent $event): bool {
99+
return $event->getParameters() === [
100+
'fileId' => 10,
101+
'user' => 'The User (1)',
102+
];
103+
})],
104+
);
105+
68106
$rule = new Rule($mapping, 10, 0b00001111, 0b00001001);
69107
$this->ruleManager->saveRule($rule);
70108

@@ -89,6 +127,9 @@ public function testGetMultiple() {
89127
->with($this->user)
90128
->willReturn([$mapping1, $mapping2]);
91129

130+
$this->eventDispatcher->expects($this->any())
131+
->method('dispatchTyped');
132+
92133
$rule1 = new Rule($mapping1, 10, 0b00001111, 0b00001001);
93134
$rule2 = new Rule($mapping2, 10, 0b00001111, 0b00001000);
94135
$rule3 = new Rule($mapping2, 11, 0b00001111, 0b00001000);
@@ -121,6 +162,9 @@ public function testGetByPath() {
121162
->with($this->user)
122163
->willReturn([$mapping]);
123164

165+
$this->eventDispatcher->expects($this->any())
166+
->method('dispatchTyped');
167+
124168
$rule1 = new Rule($mapping, $id1, 0b00001111, 0b00001001);
125169
$rule2 = new Rule($mapping, $id2, 0b00001111, 0b00001000);
126170
$this->ruleManager->saveRule($rule1);
@@ -160,6 +204,8 @@ public function testGetByPathMore() {
160204
$rule = new Rule($mapping, $id1, 0b00001111, 0b00001001);
161205
$this->ruleManager->saveRule($rule);
162206

207+
$this->eventDispatcher->expects($this->any())
208+
->method('dispatchTyped');
163209

164210
$result = $this->ruleManager->getRulesForFilesByPath($this->user, $storageId, array_merge(['foo'], $paths));
165211

0 commit comments

Comments
 (0)