Repository navigation
Unified Sharing Legacy Sync #65972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Unified Sharing Legacy Sync #65972
Changes from all commits
8d291d7
1d635ea
6bd5479
8c623ef
b47f7a8
41d9b26
71e492a
21af94c
7968c10
91c5008
839e375
1f70c33
417a326
5893022
3ebaecf
3b0344c
78e001a
e024b2d
ca742e8
84efc96
6f9a5ca
2279e86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| /** | ||
| * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later | ||
| */ | ||
|
|
||
| namespace OCA\Files\Migration; | ||
|
|
||
| use Closure; | ||
| use OCP\DB\ISchemaWrapper; | ||
| use OCP\DB\Types; | ||
| use OCP\Migration\IOutput; | ||
| use OCP\Migration\SimpleMigrationStep; | ||
| use Override; | ||
|
|
||
| final class Version35000Date20260910082613 extends SimpleMigrationStep { | ||
| /** | ||
| * @param Closure(): ISchemaWrapper $schemaClosure | ||
| */ | ||
| #[Override] | ||
| public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { | ||
| $schema = $schemaClosure(); | ||
|
|
||
| $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]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this and any code using it will need to be adjusted once #65512 is in |
||
| $sourceNodeTargetTable->addColumn('source_node_id', Types::INTEGER); | ||
| $sourceNodeTargetTable->addColumn('target', Types::TEXT, ['length' => 255]); | ||
| // Primary key doesn't work, because that makes source_instance NOT NULL | ||
| $sourceNodeTargetTable->addUniqueIndex(['user_id', 'source_instance', 'source_node_id']); | ||
|
|
||
| return $schema; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| /** | ||
| * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later | ||
| */ | ||
|
|
||
| namespace OCA\Files\Sharing\Property; | ||
|
|
||
| use NCU\Sharing\Property\ABooleanSharePropertyType; | ||
| use NCU\Sharing\Share; | ||
| use OC\Core\AppInfo\Application; | ||
| use OCP\L10N\IFactory; | ||
|
|
||
| final class NodeNicknameSharePropertyType extends ABooleanSharePropertyType { | ||
| #[\Override] | ||
| public function getDisplayName(IFactory $l10nFactory): string { | ||
| return $l10nFactory->get(Application::APP_ID)->t('Always ask recipients for a nickname before uploading files.'); | ||
| } | ||
|
|
||
| #[\Override] | ||
| public function getHint(IFactory $l10nFactory, Share $share): ?string { | ||
| return null; | ||
| } | ||
|
|
||
| #[\Override] | ||
| public function getPriority(): int { | ||
| return 75; | ||
| } | ||
|
|
||
| #[\Override] | ||
| public function isAdvanced(): bool { | ||
| return true; | ||
| } | ||
|
|
||
| #[\Override] | ||
| public function isRequired(Share $share): bool { | ||
| return false; | ||
| } | ||
|
|
||
| #[\Override] | ||
| public function getDefaultValue(Share $share): string { | ||
| return 'false'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace OCA\Files\Sharing; | ||
|
|
||
| use NCU\Sharing\Event\SharesUpdatedEvent; | ||
| use NCU\Sharing\ISharingManager; | ||
| use NCU\Sharing\ISharingRegistry; | ||
| use NCU\Sharing\ShareAccessContext; | ||
| use NCU\Sharing\ShareState; | ||
| use OCA\Files\Sharing\Source\NodeShareSourceType; | ||
| use OCP\EventDispatcher\Event; | ||
| use OCP\EventDispatcher\IEventListener; | ||
| use OCP\Files\NotFoundException; | ||
| use Override; | ||
| use RuntimeException; | ||
|
|
||
| /** | ||
| * @implements IEventListener<SharesUpdatedEvent> | ||
| */ | ||
| final readonly class SharesUpdatedListener implements IEventListener { | ||
| public function __construct( | ||
| private ISharingManager $manager, | ||
| private ISharingRegistry $registry, | ||
| private SourceNodeTargetManager $sourceNodeTargetManager, | ||
| ) { | ||
| } | ||
|
|
||
| #[Override] | ||
| public function handle(Event $event): void { | ||
| foreach ($event->shareIds as $shareId) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we send the share objects with the event to prevent having to re-fetch them here. |
||
| $share = $this->manager->getShare(new ShareAccessContext(overrideChecks: true), $shareId); | ||
| if ($share->state !== ShareState::Active) { | ||
| continue; | ||
| } | ||
|
|
||
| foreach ($share->sources as $source) { | ||
| if ($source->class !== NodeShareSourceType::class) { | ||
| continue; | ||
| } | ||
|
|
||
| $userIds = []; | ||
| foreach ($share->recipients as $recipient) { | ||
| if ($recipient->instance !== null) { | ||
| continue; | ||
| } | ||
|
|
||
| if (($recipientType = $this->registry->getRecipientTypes()[$recipient->class] ?? null) === null) { | ||
| throw new RuntimeException('The recipient type is not registered: ' . $recipient->class); | ||
| } | ||
|
|
||
| foreach ($recipientType->getUsers($recipient->value) as $userId) { | ||
| $userIds[$userId] = true; | ||
| } | ||
| } | ||
|
|
||
| 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; | ||
| } | ||
| } | ||
|
Comment on lines
+63
to
+72
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should use |
||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo it's better to have a
sendNotificationsor something property and have the tests set that tofalse.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, maybe better, mock the
$this->notifications