Repository navigation
Unified Sharing Legacy Sync - #65972
provokateurin wants to merge 22 commits into
Conversation
… the controller Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
… a hash already Signed-off-by: provokateurin <kate@provokateurin.de>
…ead of load Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
…ailable Signed-off-by: provokateurin <kate@provokateurin.de>
… unit tests Signed-off-by: provokateurin <kate@provokateurin.de>
…licit recipients Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
Signed-off-by: provokateurin <kate@provokateurin.de>
| $share->getShareType(), | ||
| $share->getPermissions() | ||
| ); | ||
| if (defined('PHPUNIT_RUN')) { |
There was a problem hiding this comment.
imo it's better to have a sendNotifications or something property and have the tests set that to false.
There was a problem hiding this comment.
Or, maybe better, mock the $this->notifications
|
|
||
| $sourceNodeTargetTable = $schema->createTable('sharing_source_node_target'); | ||
| $sourceNodeTargetTable->addColumn('user_id', Types::TEXT, ['length' => 64]); | ||
| $sourceNodeTargetTable->addColumn('source_instance', Types::STRING, ['length' => 128, 'notnull' => false]); |
There was a problem hiding this comment.
this and any code using it will need to be adjusted once #65512 is in
|
|
||
| #[Override] | ||
| public function handle(Event $event): void { | ||
| foreach ($event->shareIds as $shareId) { |
There was a problem hiding this comment.
can we send the share objects with the event to prevent having to re-fetch them here.
| $ownerUserFolder = $this->rootFolder->getUserFolder($owner->userId); | ||
| $node = $ownerUserFolder->getFirstNodeById($sourceNodeId); |
There was a problem hiding this comment.
Since this function is called in a loop for the same share, the caller should get this once and pass it
| foreach (array_keys($userIds) as $userId) { | ||
| try { | ||
| if ($this->sourceNodeTargetManager->getTarget($userId, $share->owner, (int)$source->value) === null) { | ||
| $this->sourceNodeTargetManager->createDefaultTarget($userId, $share->owner, (int)$source->value); | ||
| } | ||
| } catch (NotFoundException) { | ||
| // The same exception will happen for the other users, because the source node is the same, so we can just stop here. | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
this should use getTargets, which both fetches all existing targets at once instead of one by one, and has built-in "create default" handling.
| /** | ||
| * Get user ids for a recipient value. | ||
| * | ||
| * @return list<string> |
| if (!$share->getNoExpirationDate() || $isEnforced) { | ||
| if ($expirationDate !== null) { | ||
| $expirationDate->setTimezone($this->dateTimeZone->getTimeZone()); | ||
| $expirationDate->setTime(23, 59, 59); |
There was a problem hiding this comment.
is this behavior change intended?
|
|
||
| $legacyMappingTable = $schema->createTable('sharing_share_legacy_mapping'); | ||
| $legacyMappingTable->addColumn('id', Types::BIGINT); | ||
| $legacyMappingTable->addColumn('legacy_provider', Types::STRING, ['length' => 128]); |
There was a problem hiding this comment.
Maybe use class names and the class-mapper so we can store this as ints?
| $legacyMappingTable->addColumn('recipient_secrets', Types::TEXT); | ||
| $legacyMappingTable->addColumn('recipient_value', Types::STRING, ['length' => 255]); | ||
| $legacyMappingTable->setPrimaryKey(['legacy_provider', 'legacy_id']); | ||
| $legacyMappingTable->addIndex(['id']); |
There was a problem hiding this comment.
is id + recipient_value unique? if so, we should probably have an index for it
| * @experimental 35.0.0 | ||
| */ | ||
| public function getCreatedAt(): DateTimeImmutable { | ||
| return $this->createdAt ??= Server::get(ISnowflakeDecoder::class)->decode($this->id)->getCreatedAt(); |
There was a problem hiding this comment.
inject the decoder in the constructor instead?
| } | ||
|
|
||
| // TODO: Test | ||
| public function mapLegacyShares(?IUser $user, ?int $limit = null): void { |
There was a problem hiding this comment.
mapUnmappedLegacyShares to make it more clear that it doesn't update existing mappings
| $legacyMapping = $this->legacyMapper->createLegacyMapping( | ||
| $id, | ||
| $provider, | ||
| $row['id'], | ||
| new DateTimeImmutable(), | ||
| [$this->getSharingManager()->generateSecret()], | ||
| $this->getSharingManager()->generateSecret(), | ||
| ); | ||
|
|
||
| $this->syncLegacySharesToShare($id, [$legacyMapping]); |
There was a problem hiding this comment.
these two should be in a transaction to prevent an error halfway from causing a desync
| if ($event instanceof SharesUpdatedEvent) { | ||
| foreach ($event->shareIds as $id) { | ||
| $this->wrapSync($id, function () use ($id): void { | ||
| $share = $this->getSharingManager()->getShare(new ShareAccessContext(overrideChecks: true), $id); |
There was a problem hiding this comment.
another place where having the share in the event would save work
| new ShareUser( | ||
| $shareInitiator['value'], | ||
| $shareInitiator['instance'], | ||
| ), |
There was a problem hiding this comment.
minor nitpick: creating the ShareUser can be de-duplicated
| $this->ignoreNewLegacyShare = false; | ||
| } catch (Exception $exception) { | ||
| $this->ignoreNewLegacyShare = false; | ||
| throw $exception; | ||
| } |
There was a problem hiding this comment.
} finally {
$this->ignoreNewLegacyShare = false;
}
#64737
There are some TODOs left in the code, but I just need to get this merged, so future changes can be done in smaller PRs.
The syncing logic is not nice to understand, because it's an encoding of all the quirks and limitations the legacy sharing system has. I tried my best to leave useful comments whenever possible, but I'm happy to add more if there are questions during the review.