Skip to content

Commit f9907b0

Browse files
committed
fix: use an event to handle sharing backends setting default values on existing shares
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 3bdfedb commit f9907b0

6 files changed

Lines changed: 157 additions & 99 deletions

File tree

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
'NCU\\Security\\Signature\\ISignatureManager' => $baseDir . '/lib/unstable/Security/Signature/ISignatureManager.php',
3838
'NCU\\Security\\Signature\\ISignedRequest' => $baseDir . '/lib/unstable/Security/Signature/ISignedRequest.php',
3939
'NCU\\Security\\Signature\\Model\\Signatory' => $baseDir . '/lib/unstable/Security/Signature/Model/Signatory.php',
40+
'NCU\\Sharing\\Event\\SharesDefaultSetEvent' => $baseDir . '/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php',
4041
'NCU\\Sharing\\Exception\\AShareException' => $baseDir . '/lib/unstable/Sharing/Exception/AShareException.php',
4142
'NCU\\Sharing\\Exception\\ShareInvalidException' => $baseDir . '/lib/unstable/Sharing/Exception/ShareInvalidException.php',
4243
'NCU\\Sharing\\Exception\\ShareNotFoundException' => $baseDir . '/lib/unstable/Sharing/Exception/ShareNotFoundException.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
7878
'NCU\\Security\\Signature\\ISignatureManager' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/ISignatureManager.php',
7979
'NCU\\Security\\Signature\\ISignedRequest' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/ISignedRequest.php',
8080
'NCU\\Security\\Signature\\Model\\Signatory' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/Model/Signatory.php',
81+
'NCU\\Sharing\\Event\\SharesDefaultSetEvent' => __DIR__ . '/../../..' . '/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php',
8182
'NCU\\Sharing\\Exception\\AShareException' => __DIR__ . '/../../..' . '/lib/unstable/Sharing/Exception/AShareException.php',
8283
'NCU\\Sharing\\Exception\\ShareInvalidException' => __DIR__ . '/../../..' . '/lib/unstable/Sharing/Exception/ShareInvalidException.php',
8384
'NCU\\Sharing\\Exception\\ShareNotFoundException' => __DIR__ . '/../../..' . '/lib/unstable/Sharing/Exception/ShareNotFoundException.php',

lib/private/Sharing/SharingBackend.php

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
namespace OC\Sharing;
1111

1212
use Exception;
13+
use NCU\Sharing\Event\SharesDefaultSetEvent;
1314
use NCU\Sharing\Exception\ShareInvalidException;
1415
use NCU\Sharing\Exception\ShareNotFoundException;
1516
use NCU\Sharing\ISharingBackend;
16-
use NCU\Sharing\ISharingManager;
1717
use NCU\Sharing\ISharingRegistry;
1818
use NCU\Sharing\Permission\ISharePermissionType;
1919
use NCU\Sharing\Permission\SharePermission;
@@ -30,6 +30,7 @@
3030
use NCU\Sharing\Source\IShareSourceType;
3131
use NCU\Sharing\Source\ShareSource;
3232
use OCP\DB\QueryBuilder\IQueryBuilder;
33+
use OCP\EventDispatcher\IEventDispatcher;
3334
use OCP\IAppConfig;
3435
use OCP\IDBConnection;
3536
use OCP\IL10N;
@@ -50,7 +51,7 @@ public function __construct(
5051
private IUserManager $userManager,
5152
private IAppConfig $appConfig,
5253
private ISharingRegistry $registry,
53-
private ISharingManager $manager,
54+
private IEventDispatcher $eventDispatcher,
5455
private ClassMapper $classMapper,
5556
) {
5657
$this->l10n = $factory->get('sharing');
@@ -981,6 +982,7 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID,
981982
}
982983
}
983984

985+
$defaultSet = false;
984986
foreach (array_keys($shares) as $id) {
985987
foreach (array_keys($registryPropertyTypes) as $propertyTypeClass) {
986988
$share = $shares[$id];
@@ -989,7 +991,8 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID,
989991
&& isset($shareSourceTypeClasses[$id], $shareRecipientTypeClasses[$id])
990992
&& array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], array_keys($shareSourceTypeClasses[$id])) !== []
991993
&& array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) !== []) {
992-
$shares[$id] = $this->manager->createSharePropertyDefaultValue($shares[$id], $propertyTypeClass);
994+
$shares[$id] = $this->createSharePropertyDefaultValue($shares[$id], $propertyTypeClass);
995+
$defaultSet = true;
993996
}
994997
}
995998
}
@@ -998,11 +1001,95 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID,
9981001
foreach (array_keys($shareCompatiblePermissionTypeClasses[$id]) as $permissionTypeClass) {
9991002
$share = $shares[$id];
10001003
if (!isset($share->permissions[$permissionTypeClass])) {
1001-
$shares[$id] = $this->manager->createSharePermissionDefaultValue($shares[$id], $permissionTypeClass);
1004+
$shares[$id] = $this->createSharePermissionDefaultValue($shares[$id], $permissionTypeClass);
1005+
$defaultSet = true;
10021006
}
10031007
}
10041008
}
10051009

1006-
return array_values($shares);
1010+
$shares = array_values($shares);
1011+
if ($defaultSet && $shares !== []) {
1012+
$event = new SharesDefaultSetEvent($shares);
1013+
$this->eventDispatcher->dispatchTyped($event);
1014+
$shares = $event->getShares();
1015+
}
1016+
1017+
return $shares;
1018+
}
1019+
1020+
/**
1021+
* @return non-negative-int
1022+
*/
1023+
public function generateTimestamp(): int {
1024+
$time = (int)(microtime(true) * 1000.0);
1025+
if ($time < 0) {
1026+
throw new RuntimeException('Have you invented time travel?');
1027+
}
1028+
1029+
return $time;
1030+
}
1031+
1032+
/**
1033+
* @param class-string<ISharePropertyType> $propertyTypeClass
1034+
*/
1035+
public function createSharePropertyDefaultValue(Share $share, string $propertyTypeClass): Share {
1036+
$timestamp = $this->generateTimestamp();
1037+
$this->setLastUpdated([$share->id], $timestamp);
1038+
1039+
if (($propertyType = $this->registry->getPropertyTypes()[$propertyTypeClass] ?? null) === null) {
1040+
throw new RuntimeException('The property is not registered: ' . $propertyTypeClass);
1041+
}
1042+
1043+
$property = new ShareProperty($propertyTypeClass, $propertyType->getDefaultValue($share));
1044+
1045+
$this->createShareProperty($share->id, $property);
1046+
1047+
$properties = $share->properties;
1048+
$properties[$propertyTypeClass] = $property;
1049+
1050+
$share = new Share(
1051+
$share->id,
1052+
$share->owner,
1053+
$timestamp,
1054+
$share->state,
1055+
$share->sources,
1056+
$share->recipients,
1057+
$properties,
1058+
$share->permissions,
1059+
);
1060+
1061+
return $share;
1062+
}
1063+
1064+
/**
1065+
* @param class-string<ISharePermissionType> $permissionTypeClass
1066+
*/
1067+
public function createSharePermissionDefaultValue(Share $share, string $permissionTypeClass): Share {
1068+
$timestamp = $this->generateTimestamp();
1069+
$this->setLastUpdated([$share->id], $timestamp);
1070+
1071+
if (($permissionType = $this->registry->getPermissionTypes()[$permissionTypeClass] ?? null) === null) {
1072+
throw new RuntimeException('The permission is not registered: ' . $permissionTypeClass);
1073+
}
1074+
1075+
$permission = new SharePermission($permissionTypeClass, $permissionType->isEnabledByDefault());
1076+
1077+
$this->createSharePermission($share->id, $permission);
1078+
1079+
$permissions = $share->permissions;
1080+
$permissions[$permissionTypeClass] = $permission;
1081+
1082+
$share = new Share(
1083+
$share->id,
1084+
$share->owner,
1085+
$timestamp,
1086+
$share->state,
1087+
$share->sources,
1088+
$share->recipients,
1089+
$share->properties,
1090+
$permissions,
1091+
);
1092+
1093+
return $share;
10071094
}
10081095
}

lib/private/Sharing/SharingManager.php

Lines changed: 17 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace OC\Sharing;
1111

1212
use Exception;
13+
use NCU\Sharing\Event\SharesDefaultSetEvent;
1314
use NCU\Sharing\Exception\ShareInvalidException;
1415
use NCU\Sharing\Exception\ShareOperationForbiddenException;
1516
use NCU\Sharing\ISharingBackend;
@@ -52,7 +53,7 @@
5253

5354
/**
5455
* @psalm-import-type SharingShare from Share
55-
* @template-implements IEventListener<BeforeUserDeletedEvent>
56+
* @template-implements IEventListener<BeforeUserDeletedEvent|SharesDefaultSetEvent>
5657
*/
5758
final readonly class SharingManager implements ISharingManager, IEventListener {
5859
private Randomizer $randomizer;
@@ -429,40 +430,6 @@ public function updateShareRecipientSecret(ShareAccessContext $accessContext, st
429430
$this->processShareUpdates([$id]);
430431
}
431432

432-
#[\Override]
433-
public function createSharePropertyDefaultValue(Share $share, string $propertyTypeClass): Share {
434-
$this->assertInTransaction();
435-
436-
$timestamp = $this->generateTimestamp();
437-
$this->backend->setLastUpdated([$share->id], $timestamp);
438-
439-
if (($propertyType = $this->registry->getPropertyTypes()[$propertyTypeClass] ?? null) === null) {
440-
throw new RuntimeException('The property is not registered: ' . $propertyTypeClass);
441-
}
442-
443-
$property = new ShareProperty($propertyTypeClass, $propertyType->getDefaultValue($share));
444-
445-
$this->backend->createShareProperty($share->id, $property);
446-
447-
$properties = $share->properties;
448-
$properties[$propertyTypeClass] = $property;
449-
450-
$share = new Share(
451-
$share->id,
452-
$share->owner,
453-
$timestamp,
454-
$share->state,
455-
$share->sources,
456-
$share->recipients,
457-
$properties,
458-
$share->permissions,
459-
);
460-
461-
[$share] = $this->processShareUpdates([$share]);
462-
463-
return $share;
464-
}
465-
466433
#[\Override]
467434
public function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): void {
468435
$this->assertInTransaction();
@@ -488,40 +455,6 @@ public function updateShareProperty(ShareAccessContext $accessContext, string $i
488455
$this->processShareUpdates([$id]);
489456
}
490457

491-
#[\Override]
492-
public function createSharePermissionDefaultValue(Share $share, string $permissionTypeClass): Share {
493-
$this->assertInTransaction();
494-
495-
$timestamp = $this->generateTimestamp();
496-
$this->backend->setLastUpdated([$share->id], $timestamp);
497-
498-
if (($permissionType = $this->registry->getPermissionTypes()[$permissionTypeClass] ?? null) === null) {
499-
throw new RuntimeException('The permission is not registered: ' . $permissionTypeClass);
500-
}
501-
502-
$permission = new SharePermission($permissionTypeClass, $permissionType->isEnabledByDefault());
503-
504-
$this->backend->createSharePermission($share->id, $permission);
505-
506-
$permissions = $share->permissions;
507-
$permissions[$permissionTypeClass] = $permission;
508-
509-
$share = new Share(
510-
$share->id,
511-
$share->owner,
512-
$timestamp,
513-
$share->state,
514-
$share->sources,
515-
$share->recipients,
516-
$share->properties,
517-
$permissions,
518-
);
519-
520-
[$share] = $this->processShareUpdates([$share]);
521-
522-
return $share;
523-
}
524-
525458
#[\Override]
526459
public function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): void {
527460
$this->assertInTransaction();
@@ -611,16 +544,22 @@ public function getShares(ShareAccessContext $accessContext, ?string $filterSour
611544

612545
#[\Override]
613546
public function handle(Event $event): void {
614-
$shareUser = new ShareUser($event->getUser()->getUID(), null);
547+
if ($event instanceof SharesDefaultSetEvent) {
548+
$this->processShareUpdates($event->getShares());
549+
}
615550

616-
try {
617-
$this->dbConnection->beginTransaction();
618-
$this->onOwnerDeleted(new ShareAccessContext(overrideChecks: true), $shareUser);
619-
$this->onInitiatorDeleted(new ShareAccessContext(overrideChecks: true), $shareUser);
620-
$this->dbConnection->commit();
621-
} catch (Exception $exception) {
622-
$this->dbConnection->rollBack();
623-
throw $exception;
551+
if ($event instanceof BeforeUserDeletedEvent) {
552+
$shareUser = new ShareUser($event->getUser()->getUID(), null);
553+
554+
try {
555+
$this->dbConnection->beginTransaction();
556+
$this->onOwnerDeleted(new ShareAccessContext(overrideChecks: true), $shareUser);
557+
$this->onInitiatorDeleted(new ShareAccessContext(overrideChecks: true), $shareUser);
558+
$this->dbConnection->commit();
559+
} catch (Exception $exception) {
560+
$this->dbConnection->rollBack();
561+
throw $exception;
562+
}
624563
}
625564
}
626565

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace NCU\Sharing\Event;
11+
12+
use NCU\Sharing\Share;
13+
use OCP\EventDispatcher\Event;
14+
15+
/**
16+
* Emitted when a default value for a permission or property has been applied to an existing share
17+
*
18+
* @experimental 35.0.0
19+
*/
20+
final class SharesDefaultSetEvent extends Event {
21+
/**
22+
* @param non-empty-list<Share> $shares
23+
* @experimental 35.0.0
24+
*/
25+
public function __construct(
26+
private array $shares,
27+
) {
28+
parent::__construct();
29+
}
30+
31+
/**
32+
* @return non-empty-list<Share>
33+
* @experimental 35.0.0
34+
*/
35+
public function getShares(): array {
36+
return $this->shares;
37+
}
38+
39+
/**
40+
* @param non-empty-list<Share> $shares
41+
* @experimental 35.0.0
42+
*/
43+
public function setShares(array $shares): void {
44+
$this->shares = $shares;
45+
}
46+
}

lib/unstable/Sharing/ISharingManager.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
use NCU\Sharing\Exception\ShareNotFoundException;
1414
use NCU\Sharing\Exception\ShareOperationForbiddenException;
1515
use NCU\Sharing\Permission\ISharePermissionPreset;
16-
use NCU\Sharing\Permission\ISharePermissionType;
1716
use NCU\Sharing\Permission\SharePermission;
18-
use NCU\Sharing\Property\ISharePropertyType;
1917
use NCU\Sharing\Property\ShareProperty;
2018
use NCU\Sharing\Recipient\IShareRecipientType;
2119
use NCU\Sharing\Recipient\ShareRecipient;
@@ -150,13 +148,6 @@ public function onInitiatorDeleted(ShareAccessContext $accessContext, ShareUser
150148
*/
151149
public function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): void;
152150

153-
/**
154-
* @param class-string<ISharePropertyType> $propertyTypeClass
155-
* @throws ShareNotFoundException
156-
* @experimental 35.0.0
157-
*/
158-
public function createSharePropertyDefaultValue(Share $share, string $propertyTypeClass): Share;
159-
160151
/**
161152
* Update a property of a share.
162153
*
@@ -167,13 +158,6 @@ public function createSharePropertyDefaultValue(Share $share, string $propertyTy
167158
*/
168159
public function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): void;
169160

170-
/**
171-
* @param class-string<ISharePermissionType> $permissionTypeClass
172-
* @throws ShareNotFoundException
173-
* @experimental 35.0.0
174-
*/
175-
public function createSharePermissionDefaultValue(Share $share, string $permissionTypeClass): Share;
176-
177161
/**
178162
* Update a permission of a share.
179163
*

0 commit comments

Comments
 (0)