From 10fdbee9e2a277f76a0e682e3d1115bf89666da3 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Thu, 23 Jul 2026 13:36:49 +0200 Subject: [PATCH 1/3] fix(Sharing): Remove faulty check if required properties have a default value Signed-off-by: provokateurin --- lib/private/Sharing/SharingRegistry.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/private/Sharing/SharingRegistry.php b/lib/private/Sharing/SharingRegistry.php index 3ee949fb1ddfa..333beb3b2b2f6 100644 --- a/lib/private/Sharing/SharingRegistry.php +++ b/lib/private/Sharing/SharingRegistry.php @@ -175,10 +175,6 @@ public function getPropertyTypeCompatibleRecipientTypes(): array { public function registerPropertyType(ISharePropertyType $propertyType): void { $class = $propertyType::class; - if ($propertyType->isRequired() && $propertyType->getDefaultValue() === null) { - throw new RuntimeException('Share property type ' . $class . ' is required, but has no default value.'); - } - if (isset($this->propertyTypes[$class])) { throw new RuntimeException('Share property type ' . $class . ' is already registered'); } From b829350741946a527bcdddae0a8de5a91eb0773f Mon Sep 17 00:00:00 2001 From: provokateurin Date: Thu, 23 Jul 2026 14:31:34 +0200 Subject: [PATCH 2/3] refactor(SharingBackend): Insert default values for properties and permissions after creating the share objects Signed-off-by: provokateurin --- apps/sharing/lib/SharingBackend.php | 133 ++++++++++++++++------------ 1 file changed, 78 insertions(+), 55 deletions(-) diff --git a/apps/sharing/lib/SharingBackend.php b/apps/sharing/lib/SharingBackend.php index 28c65d3b081f0..46a1d4b628c86 100644 --- a/apps/sharing/lib/SharingBackend.php +++ b/apps/sharing/lib/SharingBackend.php @@ -813,34 +813,6 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, } } - foreach (array_keys($shares) as $id) { - foreach ($registryPropertyTypes as $propertyTypeClass => $propertyType) { - if ( - !isset($shares[$id]['properties'][$propertyTypeClass]) - && isset($shareSourceTypeClasses[$id], $shareRecipientTypeClasses[$id]) - && array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], array_keys($shareSourceTypeClasses[$id])) !== [] - && array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) !== []) { - $value = $propertyType->getDefaultValue(); - - $timestamp = $this->manager->generateTimestamp(); - $this->setLastUpdated([(string)$id], $timestamp); - - $qb = $this->connection->getQueryBuilder(); - $qb - ->insert('sharing_share_properties') - ->values([ - 'share_id' => $qb->createNamedParameter($id), - 'property_class' => $qb->createNamedParameter($propertyTypeClass), - 'property_value' => $qb->createNamedParameter($propertyType instanceof ISharePropertyTypeModifyValue ? $propertyType->modifyValueOnSave(null, $value) : $value), - ]) - ->executeStatement(); - - $shares[$id]['properties'][$propertyTypeClass] = new ShareProperty($propertyTypeClass, $value); - $shares[$id]['last_updated'] = $timestamp; - } - } - } - $registrySourceTypePermissionTypeClasses = $this->registry->getSourceTypePermissionTypeClasses(); $registryGenericPermissionTypeClasses = $this->registry->getGenericPermissionTypeClasses(); @@ -891,33 +863,6 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, } } - $permissionTypes = $this->registry->getPermissionTypes(); - - foreach (array_keys($shares) as $id) { - foreach (array_keys($shareCompatiblePermissionTypeClasses[$id]) as $permissionTypeClass) { - $permissionType = $permissionTypes[$permissionTypeClass]; - if (!isset($shares[$id]['permissions'][$permissionTypeClass])) { - $enabled = $permissionType->isEnabledByDefault(); - - $timestamp = $this->manager->generateTimestamp(); - $this->setLastUpdated([(string)$id], $timestamp); - - $qb = $this->connection->getQueryBuilder(); - $qb - ->insert('sharing_share_permissions') - ->values([ - 'share_id' => $qb->createNamedParameter($id), - 'permission_class' => $qb->createNamedParameter($permissionTypeClass), - 'permission_enabled' => $qb->createNamedParameter($enabled, IQueryBuilder::PARAM_BOOL), - ]) - ->executeStatement(); - - $shares[$id]['permissions'][$permissionTypeClass] = new SharePermission($permissionTypeClass, $enabled); - $shares[$id]['last_updated'] = $timestamp; - } - } - } - $shares = array_map(static fn (array $share): Share => new Share( $share['id'], $share['owner'], @@ -948,6 +893,84 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, } } + foreach (array_keys($shares) as $id) { + foreach ($registryPropertyTypes as $propertyTypeClass => $propertyType) { + $share = $shares[$id]; + if ( + !isset($share->properties[$propertyTypeClass]) + && isset($shareSourceTypeClasses[$id], $shareRecipientTypeClasses[$id]) + && array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], array_keys($shareSourceTypeClasses[$id])) !== [] + && array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) !== []) { + $value = $propertyType->getDefaultValue(); + + $timestamp = $this->manager->generateTimestamp(); + $this->setLastUpdated([(string)$id], $timestamp); + + $qb = $this->connection->getQueryBuilder(); + $qb + ->insert('sharing_share_properties') + ->values([ + 'share_id' => $qb->createNamedParameter($id), + 'property_class' => $qb->createNamedParameter($propertyTypeClass), + 'property_value' => $qb->createNamedParameter($propertyType instanceof ISharePropertyTypeModifyValue ? $propertyType->modifyValueOnSave(null, $value) : $value), + ]) + ->executeStatement(); + + $properties = $share->properties; + $properties[$propertyTypeClass] = new ShareProperty($propertyTypeClass, $value); + + $shares[$id] = new Share( + $share->id, + $share->owner, + $timestamp, + $share->state, + $share->sources, + $share->recipients, + $properties, + $share->permissions, + ); + } + } + } + + $permissionTypes = $this->registry->getPermissionTypes(); + foreach (array_keys($shares) as $id) { + foreach (array_keys($shareCompatiblePermissionTypeClasses[$id]) as $permissionTypeClass) { + $share = $shares[$id]; + if (!isset($share->permissions[$permissionTypeClass])) { + $permissionType = $permissionTypes[$permissionTypeClass]; + $enabled = $permissionType->isEnabledByDefault(); + + $timestamp = $this->manager->generateTimestamp(); + $this->setLastUpdated([(string)$id], $timestamp); + + $qb = $this->connection->getQueryBuilder(); + $qb + ->insert('sharing_share_permissions') + ->values([ + 'share_id' => $qb->createNamedParameter($id), + 'permission_class' => $qb->createNamedParameter($permissionTypeClass), + 'permission_enabled' => $qb->createNamedParameter($enabled, IQueryBuilder::PARAM_BOOL), + ]) + ->executeStatement(); + + $permissions = $share->permissions; + $permissions[$permissionTypeClass] = new SharePermission($permissionTypeClass, $enabled); + + $shares[$id] = new Share( + $share->id, + $share->owner, + $timestamp, + $share->state, + $share->sources, + $share->recipients, + $share->properties, + $permissions, + ); + } + } + } + return array_values($shares); } } From 098973cb8459750bfef658f762aa1e90ef53ebe3 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Thu, 23 Jul 2026 15:56:03 +0200 Subject: [PATCH 3/3] fix(Sharing): Compute required, default and max expiration date based on recipients Signed-off-by: provokateurin --- .../NodeGridViewSharePropertyType.php | 5 +- apps/sharing/lib/SharingBackend.php | 2 +- .../ExpirationDateSharePropertyType.php | 63 ++++++-- .../Property/LabelSharePropertyType.php | 5 +- .../Property/NoteSharePropertyType.php | 5 +- .../Property/PasswordSharePropertyType.php | 6 +- lib/private/Sharing/SharingManager.php | 10 +- .../Property/ABooleanSharePropertyType.php | 4 +- .../Property/ADateSharePropertyType.php | 16 +- .../Property/AEnumSharePropertyType.php | 4 +- .../Property/APasswordSharePropertyType.php | 4 +- .../Property/AStringSharePropertyType.php | 4 +- .../Sharing/Property/ISharePropertyType.php | 8 +- lib/public/Sharing/Property/ShareProperty.php | 6 +- lib/public/Sharing/Share.php | 2 +- .../ExpirationDateSharePropertyTypeTest.php | 147 ++++++++++++------ .../PasswordSharePropertyTypeTest.php | 17 +- .../ABooleanSharePropertyTypeTest.php | 25 ++- .../Property/ADateSharePropertyTypeTest.php | 27 +++- .../Property/AEnumSharePropertyTypeTest.php | 21 ++- .../APasswordSharePropertyTypeTest.php | 21 ++- .../Property/AStringSharePropertyTypeTest.php | 27 +++- tests/lib/Sharing/TestSharePropertyType1.php | 5 +- .../TestSharePropertyTypeModifyValue.php | 3 +- .../Sharing/TestSharePropertyTypeRequired.php | 6 +- 25 files changed, 307 insertions(+), 136 deletions(-) diff --git a/apps/files/lib/Sharing/Property/NodeGridViewSharePropertyType.php b/apps/files/lib/Sharing/Property/NodeGridViewSharePropertyType.php index 9aee9df7c210f..86a2c79121ef2 100644 --- a/apps/files/lib/Sharing/Property/NodeGridViewSharePropertyType.php +++ b/apps/files/lib/Sharing/Property/NodeGridViewSharePropertyType.php @@ -12,6 +12,7 @@ use OCA\Files\AppInfo\Application; use OCP\L10N\IFactory; use OCP\Sharing\Property\ABooleanSharePropertyType; +use OCP\Sharing\Share; final class NodeGridViewSharePropertyType extends ABooleanSharePropertyType { #[\Override] @@ -35,12 +36,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { return false; } #[\Override] - public function getDefaultValue(): string { + public function getDefaultValue(Share $share): string { return 'false'; } } diff --git a/apps/sharing/lib/SharingBackend.php b/apps/sharing/lib/SharingBackend.php index 46a1d4b628c86..87c176325954f 100644 --- a/apps/sharing/lib/SharingBackend.php +++ b/apps/sharing/lib/SharingBackend.php @@ -901,7 +901,7 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, && isset($shareSourceTypeClasses[$id], $shareRecipientTypeClasses[$id]) && array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], array_keys($shareSourceTypeClasses[$id])) !== [] && array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) !== []) { - $value = $propertyType->getDefaultValue(); + $value = $propertyType->getDefaultValue($share); $timestamp = $this->manager->generateTimestamp(); $this->setLastUpdated([(string)$id], $timestamp); diff --git a/core/Sharing/Property/ExpirationDateSharePropertyType.php b/core/Sharing/Property/ExpirationDateSharePropertyType.php index fac8c55a280e2..7def2d4b7eae5 100644 --- a/core/Sharing/Property/ExpirationDateSharePropertyType.php +++ b/core/Sharing/Property/ExpirationDateSharePropertyType.php @@ -13,6 +13,8 @@ use DateTimeImmutable; use DateTimeInterface; use OC\Core\AppInfo\Application; +use OC\Core\Sharing\Recipient\EmailShareRecipientType; +use OC\Core\Sharing\Recipient\TokenShareRecipientType; use OCP\L10N\IFactory; use OCP\Share\IManager; use OCP\Sharing\Property\ADateSharePropertyType; @@ -52,51 +54,50 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { - if ($this->legacyManager->shareApiLinkDefaultExpireDateEnforced()) { + public function isRequired(Share $share): bool { + if ($this->hasTokenOrEmailRecipient($share) && $this->legacyManager->shareApiLinkDefaultExpireDateEnforced()) { return true; } - if ($this->legacyManager->shareApiRemoteDefaultExpireDateEnforced()) { + if ($this->hasRemoteRecipient($share) && $this->legacyManager->shareApiRemoteDefaultExpireDateEnforced()) { return true; } - - return $this->legacyManager->shareApiInternalDefaultExpireDateEnforced(); + return $this->hasLocalNonTokenAndEmailRecipient($share) && $this->legacyManager->shareApiInternalDefaultExpireDateEnforced(); } #[\Override] - public function getDefaultValue(): ?string { - return $this->getMaxExpirationDate()?->format(DateTimeInterface::ATOM); + public function getDefaultValue(Share $share): ?string { + return $this->getMaxExpirationDate($share)?->format(DateTimeInterface::ATOM); } #[\Override] - public function getMinDate(): \DateTimeImmutable { + public function getMinDate(Share $share): \DateTimeImmutable { // Ensure the expiration date is in the future. return $this->now->add(new DateInterval('PT5M')); } #[\Override] - public function getMaxDate(): ?DateTimeImmutable { - if ($this->isRequired()) { + public function getMaxDate(Share $share): ?DateTimeImmutable { + if ($this->isRequired($share)) { // Allow some time to pass between the user getting the max date and saving the date, as the time will shift in between. - return $this->getMaxExpirationDate()?->add(new DateInterval('PT5M')); + return $this->getMaxExpirationDate($share)?->add(new DateInterval('PT5M')); } return null; } - private function getMaxExpirationDate(): ?DateTimeImmutable { - // We do not have any distinction between link/remote/internal, so we just apply the lowest expiration days count to be safe. + private function getMaxExpirationDate(Share $share): ?DateTimeImmutable { $days = INF; - if ($this->legacyManager->shareApiLinkDefaultExpireDate()) { + + if ($this->hasTokenOrEmailRecipient($share) && $this->legacyManager->shareApiLinkDefaultExpireDate()) { $days = min($days, $this->legacyManager->shareApiLinkDefaultExpireDays()); } - if ($this->legacyManager->shareApiRemoteDefaultExpireDate()) { + if ($this->hasRemoteRecipient($share) && $this->legacyManager->shareApiRemoteDefaultExpireDate()) { $days = min($days, $this->legacyManager->shareApiRemoteDefaultExpireDays()); } - if ($this->legacyManager->shareApiInternalDefaultExpireDate()) { + if ($this->hasLocalNonTokenAndEmailRecipient($share) && $this->legacyManager->shareApiInternalDefaultExpireDate()) { $days = min($days, $this->legacyManager->shareApiInternalDefaultExpireDays()); } @@ -120,4 +121,34 @@ public function isFiltered(ShareAccessContext $accessContext, Share $share): boo return false; } + + private function hasTokenOrEmailRecipient(Share $share): bool { + foreach ($share->recipients as $recipient) { + if ($recipient->class === TokenShareRecipientType::class || $recipient->class === EmailShareRecipientType::class) { + return true; + } + } + + return false; + } + + private function hasRemoteRecipient(Share $share): bool { + foreach ($share->recipients as $recipient) { + if ($recipient->instance !== null) { + return true; + } + } + + return false; + } + + private function hasLocalNonTokenAndEmailRecipient(Share $share): bool { + foreach ($share->recipients as $recipient) { + if ($recipient->instance === null && $recipient->class !== TokenShareRecipientType::class && $recipient->class !== EmailShareRecipientType::class) { + return true; + } + } + + return false; + } } diff --git a/core/Sharing/Property/LabelSharePropertyType.php b/core/Sharing/Property/LabelSharePropertyType.php index 699262ec52d19..d270d73cf06a3 100644 --- a/core/Sharing/Property/LabelSharePropertyType.php +++ b/core/Sharing/Property/LabelSharePropertyType.php @@ -12,6 +12,7 @@ use OC\Core\AppInfo\Application; use OCP\L10N\IFactory; use OCP\Sharing\Property\AStringSharePropertyType; +use OCP\Sharing\Share; final class LabelSharePropertyType extends AStringSharePropertyType { #[\Override] @@ -35,12 +36,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { return false; } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { return null; } diff --git a/core/Sharing/Property/NoteSharePropertyType.php b/core/Sharing/Property/NoteSharePropertyType.php index 685c000d1777e..e93b0c8cdceaf 100644 --- a/core/Sharing/Property/NoteSharePropertyType.php +++ b/core/Sharing/Property/NoteSharePropertyType.php @@ -12,6 +12,7 @@ use OC\Core\AppInfo\Application; use OCP\L10N\IFactory; use OCP\Sharing\Property\AStringSharePropertyType; +use OCP\Sharing\Share; final class NoteSharePropertyType extends AStringSharePropertyType { #[\Override] @@ -35,12 +36,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { return false; } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { return null; } diff --git a/core/Sharing/Property/PasswordSharePropertyType.php b/core/Sharing/Property/PasswordSharePropertyType.php index 4f9422327b7a9..5651c4e8e8265 100644 --- a/core/Sharing/Property/PasswordSharePropertyType.php +++ b/core/Sharing/Property/PasswordSharePropertyType.php @@ -56,14 +56,14 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { // TODO: Enable group memberships check based on the owner. return $this->legacyManager->shareApiLinkEnforcePassword(false); } #[\Override] - public function getDefaultValue(): ?string { - if (!$this->isRequired()) { + public function getDefaultValue(Share $share): ?string { + if (!$this->isRequired($share)) { return null; } diff --git a/lib/private/Sharing/SharingManager.php b/lib/private/Sharing/SharingManager.php index fddfe871e5155..70c8732c080fe 100644 --- a/lib/private/Sharing/SharingManager.php +++ b/lib/private/Sharing/SharingManager.php @@ -400,8 +400,11 @@ public function updateShareProperty(ShareAccessContext $accessContext, string $i throw new RuntimeException('The property is not registered: ' . $property->class); } - if ($property->value !== null && ($message = $propertyType->validateValue($this->l10nFactory, $property->value)) !== true) { - throw new ShareInvalidException('Invalid property value: ' . $property->value . ' ' . $property->class, $message); + if ($property->value !== null) { + $share = $this->getShare($accessContext, $id); + if (($message = $propertyType->validateValue($this->l10nFactory, $share, $property->value)) !== true) { + throw new ShareInvalidException('Invalid property value: ' . $property->value . ' ' . $property->class, $message); + } } $backend->updateShareProperty($id, $property); @@ -547,6 +550,7 @@ private function getBackend(?string $id): ISharingBackend { } // TODO: Support IShareOwnerlessMount + /** * @throws ShareOperationForbiddenException */ @@ -668,7 +672,7 @@ private function assertShareCanBeActive(Share $share): void { $propertyTypes = $this->registry->getPropertyTypes(); foreach ($share->properties as $propertyTypeClass => $property) { $propertyType = $propertyTypes[$propertyTypeClass]; - if ($property->value === null && $propertyType->isRequired()) { + if ($property->value === null && $propertyType->isRequired($share)) { throw new ShareInvalidException('Missing value for required property: ' . $propertyTypeClass, $this->l10n->t('You need to set a value for the %s', [$propertyType->getDisplayName($this->l10nFactory)])); } } diff --git a/lib/public/Sharing/Property/ABooleanSharePropertyType.php b/lib/public/Sharing/Property/ABooleanSharePropertyType.php index 14c2531a03f80..2b5ec9b851b4e 100644 --- a/lib/public/Sharing/Property/ABooleanSharePropertyType.php +++ b/lib/public/Sharing/Property/ABooleanSharePropertyType.php @@ -25,7 +25,7 @@ abstract class ABooleanSharePropertyType implements ISharePropertyType { * @since 35.0.0 */ #[\Override] - public function validateValue(IFactory $l10nFactory, string $value): true|string { + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string { if ($value === 'true' || $value === 'false') { return true; } @@ -39,7 +39,7 @@ public function validateValue(IFactory $l10nFactory, string $value): true|string * @since 35.0.0 */ #[\Override] - public function format(array $property): array { + public function format(Share $share, array $property): array { $property['type'] = 'boolean'; return $property; } diff --git a/lib/public/Sharing/Property/ADateSharePropertyType.php b/lib/public/Sharing/Property/ADateSharePropertyType.php index 0f1f6030ceb9b..3d91890c17395 100644 --- a/lib/public/Sharing/Property/ADateSharePropertyType.php +++ b/lib/public/Sharing/Property/ADateSharePropertyType.php @@ -27,18 +27,18 @@ abstract class ADateSharePropertyType implements ISharePropertyType { /** * @since 35.0.0 */ - abstract public function getMinDate(): ?DateTimeImmutable; + abstract public function getMinDate(Share $share): ?DateTimeImmutable; /** * @since 35.0.0 */ - abstract public function getMaxDate(): ?DateTimeImmutable; + abstract public function getMaxDate(Share $share): ?DateTimeImmutable; /** * @since 35.0.0 */ #[\Override] - public function validateValue(IFactory $l10nFactory, string $value): true|string { + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string { try { $date = DateTimeImmutable::createFromFormat(DateTimeInterface::ATOM, $value); } catch (Exception) { @@ -49,11 +49,11 @@ public function validateValue(IFactory $l10nFactory, string $value): true|string return $l10nFactory->get(Application::APP_ID)->t('Invalid ISO date: %s', [$value]); } - if (($minDate = $this->getMinDate()) instanceof DateTimeImmutable && $date->diff($minDate)->invert === 0) { + if (($minDate = $this->getMinDate($share)) instanceof DateTimeImmutable && $date->diff($minDate)->invert === 0) { return $l10nFactory->get(Application::APP_ID)->t('Date needs to be after %1$s: %2$s', [$minDate->format(DateTimeInterface::ATOM), $value]); } - if (($maxDate = $this->getMaxDate()) instanceof DateTimeImmutable && $date->diff($maxDate)->invert === 1) { + if (($maxDate = $this->getMaxDate($share)) instanceof DateTimeImmutable && $date->diff($maxDate)->invert === 1) { return $l10nFactory->get(Application::APP_ID)->t('Date needs to be before %1$s: %2$s', [$maxDate->format(DateTimeInterface::ATOM), $value]); } @@ -66,10 +66,10 @@ public function validateValue(IFactory $l10nFactory, string $value): true|string * @since 35.0.0 */ #[\Override] - public function format(array $property): array { + public function format(Share $share, array $property): array { $property['type'] = 'date'; - $property['min_date'] = $this->getMinDate()?->format(DateTimeInterface::ATOM); - $property['max_date'] = $this->getMaxDate()?->format(DateTimeInterface::ATOM); + $property['min_date'] = $this->getMinDate($share)?->format(DateTimeInterface::ATOM); + $property['max_date'] = $this->getMaxDate($share)?->format(DateTimeInterface::ATOM); return $property; } } diff --git a/lib/public/Sharing/Property/AEnumSharePropertyType.php b/lib/public/Sharing/Property/AEnumSharePropertyType.php index ce376ee3dc12f..9ce85deb5f831 100644 --- a/lib/public/Sharing/Property/AEnumSharePropertyType.php +++ b/lib/public/Sharing/Property/AEnumSharePropertyType.php @@ -31,7 +31,7 @@ abstract public function getValidValues(): array; * @since 35.0.0 */ #[\Override] - public function validateValue(IFactory $l10nFactory, string $value): true|string { + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string { $validValues = $this->getValidValues(); if (in_array($value, $validValues, true)) { return true; @@ -46,7 +46,7 @@ public function validateValue(IFactory $l10nFactory, string $value): true|string * @since 35.0.0 */ #[\Override] - public function format(array $property): array { + public function format(Share $share, array $property): array { $property['type'] = 'enum'; $property['valid_values'] = $this->getValidValues(); return $property; diff --git a/lib/public/Sharing/Property/APasswordSharePropertyType.php b/lib/public/Sharing/Property/APasswordSharePropertyType.php index f3215317ac0a4..1573a33d2c17f 100644 --- a/lib/public/Sharing/Property/APasswordSharePropertyType.php +++ b/lib/public/Sharing/Property/APasswordSharePropertyType.php @@ -47,7 +47,7 @@ private function getHasher(): IHasher { * @since 35.0.0 */ #[\Override] - public function validateValue(IFactory $l10nFactory, string $value): true|string { + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string { if ($value === self::PLACEHOLDER) { return true; } @@ -94,7 +94,7 @@ public function modifyValueOnLoad(?string $value): ?string { * @since 35.0.0 */ #[\Override] - public function format(array $property): array { + public function format(Share $share, array $property): array { $property['type'] = 'password'; return $property; } diff --git a/lib/public/Sharing/Property/AStringSharePropertyType.php b/lib/public/Sharing/Property/AStringSharePropertyType.php index 34b7cc9bab03c..d1577dd6c32f4 100644 --- a/lib/public/Sharing/Property/AStringSharePropertyType.php +++ b/lib/public/Sharing/Property/AStringSharePropertyType.php @@ -37,7 +37,7 @@ abstract public function getMaxLength(): ?int; * @since 35.0.0 */ #[\Override] - public function validateValue(IFactory $l10nFactory, string $value): true|string { + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string { if (($minLength = $this->getMinLength()) !== null && mb_strlen($value) < $minLength) { return $l10nFactory->get(Application::APP_ID)->t('Need at least %1$s characters: %2$s', [$minLength, $value]); } @@ -55,7 +55,7 @@ public function validateValue(IFactory $l10nFactory, string $value): true|string * @since 35.0.0 */ #[\Override] - public function format(array $property): array { + public function format(Share $share, array $property): array { $property['type'] = 'string'; $property['min_length'] = $this->getMinLength(); $property['max_length'] = $this->getMaxLength(); diff --git a/lib/public/Sharing/Property/ISharePropertyType.php b/lib/public/Sharing/Property/ISharePropertyType.php index 877a261c21e8a..9a06a82bf7a1a 100644 --- a/lib/public/Sharing/Property/ISharePropertyType.php +++ b/lib/public/Sharing/Property/ISharePropertyType.php @@ -66,7 +66,7 @@ public function isAdvanced(): bool; * * @since 35.0.0 */ - public function isRequired(): bool; + public function isRequired(Share $share): bool; /** * The default value if the user hasn't provided one. @@ -77,7 +77,7 @@ public function isRequired(): bool; * * @since 35.0.0 */ - public function getDefaultValue(): ?string; + public function getDefaultValue(Share $share): ?string; /** * Validates the value when the share is created or updated in the database. @@ -86,12 +86,12 @@ public function getDefaultValue(): ?string; * * @since 35.0.0 */ - public function validateValue(IFactory $l10nFactory, string $value): true|string; + public function validateValue(IFactory $l10nFactory, Share $share, string $value): true|string; /** * @param SharingProperty $property * @return SharingPropertyBoolean|SharingPropertyDate|SharingPropertyEnum|SharingPropertyPassword|SharingPropertyString * @since 35.0.0 */ - public function format(array $property): array; + public function format(Share $share, array $property): array; } diff --git a/lib/public/Sharing/Property/ShareProperty.php b/lib/public/Sharing/Property/ShareProperty.php index d120a3b52864d..4acdc5a11feea 100644 --- a/lib/public/Sharing/Property/ShareProperty.php +++ b/lib/public/Sharing/Property/ShareProperty.php @@ -39,18 +39,18 @@ public function __construct( * @return SharingPropertyBoolean|SharingPropertyDate|SharingPropertyEnum|SharingPropertyPassword|SharingPropertyString * @since 35.0.0 */ - public function format(ISharingRegistry $registry, IFactory $l10nFactory): array { + public function format(ISharingRegistry $registry, IFactory $l10nFactory, Share $share): array { if (($propertyType = ($registry->getPropertyTypes()[$this->class] ?? null)) === null) { throw new RuntimeException('The property type is not registered: ' . $this->class); } - return $propertyType->format([ + return $propertyType->format($share, [ 'class' => $this->class, 'display_name' => $propertyType->getDisplayName($l10nFactory), 'hint' => $propertyType->getHint($l10nFactory), 'priority' => $propertyType->getPriority(), 'advanced' => $propertyType->isAdvanced(), - 'required' => $propertyType->isRequired(), + 'required' => $propertyType->isRequired($share), 'value' => $this->value, ]); } diff --git a/lib/public/Sharing/Share.php b/lib/public/Sharing/Share.php index 8d7c2ee28dcd1..054b4dc3b3b08 100644 --- a/lib/public/Sharing/Share.php +++ b/lib/public/Sharing/Share.php @@ -181,7 +181,7 @@ public function getEnabledPermissions(): array { * @since 35.0.0 */ public function format(ISharingRegistry $registry, IFactory $l10nFactory, IURLGenerator $urlGenerator, IUserManager $userManager): array { - $properties = array_map(static fn (ShareProperty $property): array => $property->format($registry, $l10nFactory), array_values($this->properties)); + $properties = array_map(fn (ShareProperty $property): array => $property->format($registry, $l10nFactory, $this), array_values($this->properties)); // First sort by priority and then sort by class name to get a stable order regardless of the DB order usort($properties, static fn (array $a, array $b): int => 2 * ($b['priority'] <=> $a['priority']) + ($a['class'] <=> $b['class'])); diff --git a/tests/Core/Sharing/Property/ExpirationDateSharePropertyTypeTest.php b/tests/Core/Sharing/Property/ExpirationDateSharePropertyTypeTest.php index f4c5fb1f854fd..48dba4e402b15 100644 --- a/tests/Core/Sharing/Property/ExpirationDateSharePropertyTypeTest.php +++ b/tests/Core/Sharing/Property/ExpirationDateSharePropertyTypeTest.php @@ -14,11 +14,15 @@ use DateTimeInterface; use OC\Core\AppInfo\Application; use OC\Core\Sharing\Property\ExpirationDateSharePropertyType; +use OC\Core\Sharing\Recipient\EmailShareRecipientType; +use OC\Core\Sharing\Recipient\TokenShareRecipientType; +use OC\Core\Sharing\Recipient\UserShareRecipientType; use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use OCP\Server; use OCP\Sharing\Property\ShareProperty; +use OCP\Sharing\Recipient\ShareRecipient; use OCP\Sharing\Share; use OCP\Sharing\ShareAccessContext; use OCP\Sharing\ShareState; @@ -33,6 +37,14 @@ final class ExpirationDateSharePropertyTypeTest extends TestCase { private ExpirationDateSharePropertyType $propertyType; + private ShareRecipient $tokenRecipient; + + private ShareRecipient $emailRecipient; + + private ShareRecipient $remoteRecipient; + + private ShareRecipient $localNonTokenAndEmailRecipient; + #[\Override] public function setUp(): void { parent::setUp(); @@ -42,6 +54,11 @@ public function setUp(): void { $this->user = $user; $this->propertyType = Server::get(ExpirationDateSharePropertyType::class); + + $this->tokenRecipient = new ShareRecipient(TokenShareRecipientType::class, 'token', null); + $this->emailRecipient = new ShareRecipient(EmailShareRecipientType::class, 'example@example.com', null); + $this->remoteRecipient = new ShareRecipient(UserShareRecipientType::class, 'user', 'https://example.com'); + $this->localNonTokenAndEmailRecipient = new ShareRecipient(UserShareRecipientType::class, 'user', null); } #[\Override] @@ -64,90 +81,126 @@ private function createDummyShare(ShareProperty $property): Share { ); } + /** + * @return list + */ + public static function dataConfigKeys(): array { + return [ + ['shareapi_default_expire_date', 'shareapi_enforce_expire_date', 'shareapi_expire_after_n_days'], + ['shareapi_default_remote_expire_date', 'shareapi_enforce_remote_expire_date', 'shareapi_remote_expire_after_n_days'], + ['shareapi_default_internal_expire_date', 'shareapi_enforce_internal_expire_date', 'shareapi_internal_expire_after_n_days'], + ]; + } + /** @psalm-suppress DeprecatedMethod The configs are only partly migrated to IAppConfig, so using deprecated IConfig is easier for now. */ - public function testGetRequired(): void { - $config = Server::get(IConfig::class); - $config->setAppValue(Application::APP_ID, 'shareapi_default_expire_date', 'yes'); - $config->setAppValue(Application::APP_ID, 'shareapi_default_remote_expire_date', 'yes'); - $config->setAppValue(Application::APP_ID, 'shareapi_default_internal_expire_date', 'yes'); + #[DataProvider('dataConfigKeys')] + public function testGetRequired(string $defaultEnabledKey, string $defaultEnforcedKey, string $defaultValueKey): void { + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [ + $this->tokenRecipient, + $this->emailRecipient, + $this->remoteRecipient, + $this->localNonTokenAndEmailRecipient, + ], + [], + [], + ); - $keys = ['shareapi_enforce_expire_date', 'shareapi_enforce_remote_expire_date', 'shareapi_enforce_internal_expire_date']; - foreach ($keys as $key) { + $config = Server::get(IConfig::class); + foreach (array_merge(...self::dataConfigKeys()) as $key) { $config->deleteAppValue(Application::APP_ID, $key); } - $this->assertFalse($this->propertyType->isRequired()); + $config->setAppValue(Application::APP_ID, $defaultEnabledKey, 'yes'); - foreach ($keys as $key) { - $config->setAppValue(Application::APP_ID, $key, 'yes'); - $this->assertTrue($this->propertyType->isRequired(), $key); - $config->deleteAppValue(Application::APP_ID, $key); - } + $this->assertFalse($this->propertyType->isRequired($share)); - $this->assertFalse($this->propertyType->isRequired()); + $config->setAppValue(Application::APP_ID, $defaultEnforcedKey, 'yes'); + $this->assertTrue($this->propertyType->isRequired($share)); - $config->deleteAppValue(Application::APP_ID, 'shareapi_default_expire_date'); - $config->deleteAppValue(Application::APP_ID, 'shareapi_default_remote_expire_date'); - $config->deleteAppValue(Application::APP_ID, 'shareapi_default_internal_expire_date'); + $config->deleteAppValue(Application::APP_ID, $defaultEnabledKey); + $config->deleteAppValue(Application::APP_ID, $defaultEnforcedKey); } /** @psalm-suppress DeprecatedMethod The configs are only partly migrated to IAppConfig, so using deprecated IConfig is easier for now. */ - public function testGetDefaultValue(): void { + #[DataProvider('dataConfigKeys')] + public function testGetDefaultValue(string $defaultEnabledKey, string $defaultEnforcedKey, string $defaultValueKey): void { + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [ + $this->tokenRecipient, + $this->emailRecipient, + $this->remoteRecipient, + $this->localNonTokenAndEmailRecipient, + ], + [], + [], + ); + /** @var DateTimeImmutable $now */ $now = self::invokePrivate($this->propertyType, 'now'); $config = Server::get(IConfig::class); - - $keys = ['shareapi_default_expire_date', 'shareapi_default_remote_expire_date', 'shareapi_default_internal_expire_date']; - foreach ($keys as $key) { + foreach (array_merge(...self::dataConfigKeys()) as $key) { $config->deleteAppValue(Application::APP_ID, $key); } - $this->assertNull($this->propertyType->getDefaultValue()); + $this->assertNull($this->propertyType->getDefaultValue($share)); - foreach ($keys as $key) { - $config->setAppValue(Application::APP_ID, $key, 'yes'); - $this->assertEquals($now->add(new DateInterval('P7D'))->format(DateTimeInterface::ATOM), $this->propertyType->getDefaultValue()); - $config->deleteAppValue(Application::APP_ID, $key); - } - } - - /** - * @return list - */ - public static function dataGetMinMaxDate(): array { - return [ - ['shareapi_default_expire_date', 'shareapi_enforce_expire_date', 'shareapi_expire_after_n_days'], - ['shareapi_default_remote_expire_date', 'shareapi_enforce_remote_expire_date', 'shareapi_remote_expire_after_n_days'], - ['shareapi_default_internal_expire_date', 'shareapi_enforce_internal_expire_date', 'shareapi_internal_expire_after_n_days'], - ]; + $config->setAppValue(Application::APP_ID, $defaultEnabledKey, 'yes'); + $this->assertEquals($now->add(new DateInterval('P7D'))->format(DateTimeInterface::ATOM), $this->propertyType->getDefaultValue($share)); + $config->deleteAppValue(Application::APP_ID, $defaultEnabledKey); } /** @psalm-suppress DeprecatedMethod The configs are only partly migrated to IAppConfig, so using deprecated IConfig is easier for now. */ - #[DataProvider('dataGetMinMaxDate')] + #[DataProvider('dataConfigKeys')] public function testGetMinMaxDate(string $defaultEnabledKey, string $defaultEnforcedKey, string $defaultValueKey): void { + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [ + $this->tokenRecipient, + $this->emailRecipient, + $this->remoteRecipient, + $this->localNonTokenAndEmailRecipient, + ], + [], + [], + ); + /** @var DateTimeImmutable $now */ $now = self::invokePrivate($this->propertyType, 'now'); $config = Server::get(IConfig::class); - - foreach (array_merge(...self::dataGetMinMaxDate()) as $key) { + foreach (array_merge(...self::dataConfigKeys()) as $key) { $config->deleteAppValue(Application::APP_ID, $key); } - $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate()); - $this->assertNull($this->propertyType->getMaxDate()); + $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate($share)); + $this->assertNull($this->propertyType->getMaxDate($share)); $config->setAppValue(Application::APP_ID, $defaultEnabledKey, 'yes'); - $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate()); - $this->assertNull($this->propertyType->getMaxDate()); + $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate($share)); + $this->assertNull($this->propertyType->getMaxDate($share)); $config->setAppValue(Application::APP_ID, $defaultEnforcedKey, 'yes'); $config->setAppValue(Application::APP_ID, $defaultValueKey, '123'); - $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate()); - $this->assertEquals($now->add(new DateInterval('P123DT5M')), $this->propertyType->getMaxDate()); + $this->assertEquals($now->add(new DateInterval('PT5M')), $this->propertyType->getMinDate($share)); + $this->assertEquals($now->add(new DateInterval('P123DT5M')), $this->propertyType->getMaxDate($share)); $config->deleteAppValue(Application::APP_ID, $defaultEnabledKey); $config->deleteAppValue(Application::APP_ID, $defaultEnforcedKey); diff --git a/tests/Core/Sharing/Property/PasswordSharePropertyTypeTest.php b/tests/Core/Sharing/Property/PasswordSharePropertyTypeTest.php index c558805c2473b..db0645965ee45 100644 --- a/tests/Core/Sharing/Property/PasswordSharePropertyTypeTest.php +++ b/tests/Core/Sharing/Property/PasswordSharePropertyTypeTest.php @@ -69,18 +69,29 @@ private function createDummyShare(?ShareProperty $property): Share { } public function testGetDefaultValue(): void { + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $appConfig = Server::get(IAppConfig::class); $appConfig->deleteKey(Application::APP_ID, ConfigLexicon::SHARE_LINK_PASSWORD_ENFORCED); - $this->assertNull($this->propertyType->getDefaultValue()); + $this->assertNull($this->propertyType->getDefaultValue($share)); $appConfig->setValueBool(Application::APP_ID, ConfigLexicon::SHARE_LINK_PASSWORD_ENFORCED, true); - $value = $this->propertyType->getDefaultValue(); + $value = $this->propertyType->getDefaultValue($share); $this->assertNotNull($value); /** @psalm-suppress RedundantCastGivenDocblockType psalm:strict and rector:strict fight over the cast -_- */ $this->assertGreaterThan(1, strlen((string)$value)); - $this->assertTrue($this->propertyType->validateValue(Server::get(IFactory::class), $value)); + $this->assertTrue($this->propertyType->validateValue(Server::get(IFactory::class), $share, $value)); $appConfig->deleteKey(Application::APP_ID, ConfigLexicon::SHARE_LINK_PASSWORD_ENFORCED); } diff --git a/tests/lib/Sharing/Property/ABooleanSharePropertyTypeTest.php b/tests/lib/Sharing/Property/ABooleanSharePropertyTypeTest.php index 5b10601bcb9e9..7be79c2f8016f 100644 --- a/tests/lib/Sharing/Property/ABooleanSharePropertyTypeTest.php +++ b/tests/lib/Sharing/Property/ABooleanSharePropertyTypeTest.php @@ -12,6 +12,9 @@ use OCP\L10N\IFactory; use OCP\Server; use OCP\Sharing\Property\ABooleanSharePropertyType; +use OCP\Sharing\Share; +use OCP\Sharing\ShareState; +use OCP\Sharing\ShareUser; use Test\TestCase; final class TestBooleanSharePropertyType extends ABooleanSharePropertyType { @@ -36,12 +39,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { throw new \RuntimeException(); } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { throw new \RuntimeException(); } } @@ -58,9 +61,19 @@ public function setUp(): void { public function testValidateValue(): void { $l10nFactory = Server::get(IFactory::class); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'true')); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'false')); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, '')); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, 'invalid')); + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'true')); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'false')); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, '')); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, 'invalid')); } } diff --git a/tests/lib/Sharing/Property/ADateSharePropertyTypeTest.php b/tests/lib/Sharing/Property/ADateSharePropertyTypeTest.php index 24e1718e62bc5..2151e3cc8f123 100644 --- a/tests/lib/Sharing/Property/ADateSharePropertyTypeTest.php +++ b/tests/lib/Sharing/Property/ADateSharePropertyTypeTest.php @@ -15,6 +15,9 @@ use OCP\L10N\IFactory; use OCP\Server; use OCP\Sharing\Property\ADateSharePropertyType; +use OCP\Sharing\Share; +use OCP\Sharing\ShareState; +use OCP\Sharing\ShareUser; use Test\TestCase; final class TestDateSharePropertyType extends ADateSharePropertyType { @@ -25,12 +28,12 @@ public function __construct( } #[\Override] - public function getMinDate(): ?DateTimeImmutable { + public function getMinDate(Share $share): ?DateTimeImmutable { return $this->minDate; } #[\Override] - public function getMaxDate(): ?DateTimeImmutable { + public function getMaxDate(Share $share): ?DateTimeImmutable { return $this->maxDate; } @@ -55,12 +58,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { throw new \RuntimeException(); } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { throw new \RuntimeException(); } } @@ -83,8 +86,18 @@ public function setUp(): void { public function testValidateValue(): void { $l10nFactory = Server::get(IFactory::class); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, $this->now->format(DateTimeInterface::ATOM))); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, $this->now->sub(new DateInterval('PT2M'))->format(DateTimeInterface::ATOM))); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, $this->now->add(new DateInterval('PT2M'))->format(DateTimeInterface::ATOM))); + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, $this->now->format(DateTimeInterface::ATOM))); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, $this->now->sub(new DateInterval('PT2M'))->format(DateTimeInterface::ATOM))); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, $this->now->add(new DateInterval('PT2M'))->format(DateTimeInterface::ATOM))); } } diff --git a/tests/lib/Sharing/Property/AEnumSharePropertyTypeTest.php b/tests/lib/Sharing/Property/AEnumSharePropertyTypeTest.php index 451ad1d51f42f..3e59588ffc907 100644 --- a/tests/lib/Sharing/Property/AEnumSharePropertyTypeTest.php +++ b/tests/lib/Sharing/Property/AEnumSharePropertyTypeTest.php @@ -12,6 +12,9 @@ use OCP\L10N\IFactory; use OCP\Server; use OCP\Sharing\Property\AEnumSharePropertyType; +use OCP\Sharing\Share; +use OCP\Sharing\ShareState; +use OCP\Sharing\ShareUser; use Test\TestCase; final class TestEnumSharePropertyType extends AEnumSharePropertyType { @@ -50,12 +53,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { throw new \RuntimeException(); } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { throw new \RuntimeException(); } } @@ -72,7 +75,17 @@ public function setUp(): void { public function testValidateValue(): void { $l10nFactory = Server::get(IFactory::class); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'valid')); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, 'invalid')); + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'valid')); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, 'invalid')); } } diff --git a/tests/lib/Sharing/Property/APasswordSharePropertyTypeTest.php b/tests/lib/Sharing/Property/APasswordSharePropertyTypeTest.php index b54f085b1aebb..d0d3d59c041e6 100644 --- a/tests/lib/Sharing/Property/APasswordSharePropertyTypeTest.php +++ b/tests/lib/Sharing/Property/APasswordSharePropertyTypeTest.php @@ -16,6 +16,9 @@ use OCP\Security\IHasher; use OCP\Server; use OCP\Sharing\Property\APasswordSharePropertyType; +use OCP\Sharing\Share; +use OCP\Sharing\ShareState; +use OCP\Sharing\ShareUser; use RuntimeException; use Test\TestCase; @@ -41,12 +44,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { throw new RuntimeException(); } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { throw new RuntimeException(); } } @@ -86,8 +89,18 @@ protected function tearDown(): void { public function testValidateValue(): void { $l10nFactory = Server::get(IFactory::class); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'secure')); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, '123')); + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'secure')); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, '123')); } public function testModifyValueOnFetch(): void { diff --git a/tests/lib/Sharing/Property/AStringSharePropertyTypeTest.php b/tests/lib/Sharing/Property/AStringSharePropertyTypeTest.php index 9568a607f1cfe..6838fd2c93337 100644 --- a/tests/lib/Sharing/Property/AStringSharePropertyTypeTest.php +++ b/tests/lib/Sharing/Property/AStringSharePropertyTypeTest.php @@ -12,6 +12,9 @@ use OCP\L10N\IFactory; use OCP\Server; use OCP\Sharing\Property\AStringSharePropertyType; +use OCP\Sharing\Share; +use OCP\Sharing\ShareState; +use OCP\Sharing\ShareUser; use Test\TestCase; final class TestStringSharePropertyType extends AStringSharePropertyType { @@ -54,12 +57,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { throw new \RuntimeException(); } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { throw new \RuntimeException(); } } @@ -79,10 +82,20 @@ public function setUp(): void { public function testValiStringValue(): void { $l10nFactory = Server::get(IFactory::class); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, 'ab')); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'abc')); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'abcd')); - $this->assertTrue($this->propertyType->validateValue($l10nFactory, 'abcde')); - $this->assertIsString($this->propertyType->validateValue($l10nFactory, 'abcdef')); + $share = new Share( + '123', + new ShareUser('user', null), + 0, + ShareState::Active, + [], + [], + [], + [], + ); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, 'ab')); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'abc')); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'abcd')); + $this->assertTrue($this->propertyType->validateValue($l10nFactory, $share, 'abcde')); + $this->assertIsString($this->propertyType->validateValue($l10nFactory, $share, 'abcdef')); } } diff --git a/tests/lib/Sharing/TestSharePropertyType1.php b/tests/lib/Sharing/TestSharePropertyType1.php index 4f5f88571f34a..3e9fb15e81908 100644 --- a/tests/lib/Sharing/TestSharePropertyType1.php +++ b/tests/lib/Sharing/TestSharePropertyType1.php @@ -11,6 +11,7 @@ use OCP\L10N\IFactory; use OCP\Sharing\Property\AEnumSharePropertyType; +use OCP\Sharing\Share; class TestSharePropertyType1 extends AEnumSharePropertyType { public function __construct( @@ -42,12 +43,12 @@ public function isAdvanced(): bool { } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { return false; } #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { return null; } diff --git a/tests/lib/Sharing/TestSharePropertyTypeModifyValue.php b/tests/lib/Sharing/TestSharePropertyTypeModifyValue.php index 1a784b1b271cd..a00ff4900f369 100644 --- a/tests/lib/Sharing/TestSharePropertyTypeModifyValue.php +++ b/tests/lib/Sharing/TestSharePropertyTypeModifyValue.php @@ -10,11 +10,12 @@ namespace Test\Sharing; use OCP\Sharing\Property\ISharePropertyTypeModifyValue; +use OCP\Sharing\Share; final class TestSharePropertyTypeModifyValue extends TestSharePropertyType1 implements ISharePropertyTypeModifyValue { #[\Override] - public function getDefaultValue(): string { + public function getDefaultValue(Share $share): string { return 'modify-on-save'; } diff --git a/tests/lib/Sharing/TestSharePropertyTypeRequired.php b/tests/lib/Sharing/TestSharePropertyTypeRequired.php index 3d660c84c7709..778c55dce07eb 100644 --- a/tests/lib/Sharing/TestSharePropertyTypeRequired.php +++ b/tests/lib/Sharing/TestSharePropertyTypeRequired.php @@ -9,14 +9,16 @@ namespace Test\Sharing; +use OCP\Sharing\Share; + final class TestSharePropertyTypeRequired extends TestSharePropertyType1 { #[\Override] - public function getDefaultValue(): ?string { + public function getDefaultValue(Share $share): ?string { return $this->getValidValues()[0]; } #[\Override] - public function isRequired(): bool { + public function isRequired(Share $share): bool { return true; } }