diff --git a/src/Controllers/LinkFieldController.php b/src/Controllers/LinkFieldController.php index f540803e..2e5bb2bc 100644 --- a/src/Controllers/LinkFieldController.php +++ b/src/Controllers/LinkFieldController.php @@ -127,17 +127,20 @@ private function getLinkData(Link $link): array */ public function linkDelete(): HTTPResponse { - $link = $this->linkFromRequest(); - if (!$link->canDelete()) { - $this->jsonError(403); - } // Check security token on destructive operation if (!SecurityToken::inst()->checkRequest($this->getRequest())) { $this->jsonError(400); } + $link = $this->linkFromRequest(); if ($link->hasExtension(Versioned::class)) { + if (!$link->canArchive()) { + $this->jsonError(403); + } $link->doArchive(); } else { + if (!$link->canDelete()) { + $this->jsonError(403); + } $link->delete(); } // Send response diff --git a/tests/php/Controllers/LinkFieldControllerTest.php b/tests/php/Controllers/LinkFieldControllerTest.php index 4b33e003..18125bd4 100644 --- a/tests/php/Controllers/LinkFieldControllerTest.php +++ b/tests/php/Controllers/LinkFieldControllerTest.php @@ -11,6 +11,7 @@ use SilverStripe\LinkField\Controllers\LinkFieldController; use SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner; use SilverStripe\Versioned\Versioned; +use SilverStripe\LinkField\Models\Link; class LinkFieldControllerTest extends FunctionalTest { @@ -528,14 +529,20 @@ public function provideLinkData(): array } /** - * @dataProvider provideLinkDelete + * @dataProvider provideLinkArchive */ - public function testLinkDelete( + public function testLinkArchive( string $idType, string $fail, int $expectedCode ): void { TestPhoneLink::$fail = $fail; + if ($fail == 'can-delete') { + // Remove the Versioned extension because there's logic in LinkFieldController + // to use either canArchive() or canDelete() based on the presence of the Versioned extension + // Note that you must remove the extension on the base class rather than a TestOnly subclass + Link::remove_extension(Versioned::class); + } $owner = $this->getFixtureLinkOwner(); $ownerID = $owner->ID; $ownerClass = urlencode($owner->ClassName); @@ -562,7 +569,7 @@ public function testLinkDelete( } } - public function provideLinkDelete(): array + public function provideLinkArchive(): array { return [ 'Valid' => [ @@ -570,6 +577,11 @@ public function provideLinkDelete(): array 'fail' => '', 'expectedCode' => 204, ], + 'Reject fail canArchive()' => [ + 'idType' => 'existing', + 'fail' => 'can-archive', + 'expectedCode' => 403, + ], 'Reject fail canDelete()' => [ 'idType' => 'existing', 'fail' => 'can-delete', diff --git a/tests/php/Controllers/LinkFieldControllerTest/TestPhoneLink.php b/tests/php/Controllers/LinkFieldControllerTest/TestPhoneLink.php index c740e1e1..b1f39bfa 100644 --- a/tests/php/Controllers/LinkFieldControllerTest/TestPhoneLink.php +++ b/tests/php/Controllers/LinkFieldControllerTest/TestPhoneLink.php @@ -43,6 +43,11 @@ public function canDelete($member = null) return TestPhoneLink::$fail !== 'can-delete'; } + public function canArchive($member = null) + { + return TestPhoneLink::$fail !== 'can-archive'; + } + public function validate(): ValidationResult { $validationResult = parent::validate();