diff --git a/client/javascript/BrokenExternalLinksReport.js b/client/javascript/BrokenExternalLinksReport.js index de33077..df95640 100644 --- a/client/javascript/BrokenExternalLinksReport.js +++ b/client/javascript/BrokenExternalLinksReport.js @@ -17,6 +17,7 @@ }, start: function() { + var self = this; // initiate a new job $('.external-links-report__report-progress') .empty() @@ -25,10 +26,21 @@ $.ajax({ url: "admin/externallinks/start", async: true, - timeout: 3000 - }); + timeout: 3000, + success: function() { + self.poll(); + }, + error: function(e) { + if (typeof console !== 'undefined') { + let message = (e && e.responseText) + ? e.responseText + : 'You do not have permission to access this resource'; - this.poll(); + console.error(message); + } + self.buttonReset(); + } + }); }, /** @@ -127,7 +139,10 @@ }, error: function(e) { if (typeof console !== 'undefined') { - console.log(e); + let message = (e && e.responseText) + ? e.responseText + : e; + console.error(message); } self.buttonReset(); } diff --git a/src/Controllers/CMSExternalLinksController.php b/src/Controllers/CMSExternalLinksController.php index a6cae46..fb9fdc2 100644 --- a/src/Controllers/CMSExternalLinksController.php +++ b/src/Controllers/CMSExternalLinksController.php @@ -8,6 +8,8 @@ use SilverStripe\Control\Controller; use Symbiote\QueuedJobs\Services\QueuedJobService; use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware; +use SilverStripe\Security\Permission; +use SilverStripe\Security\Security; class CMSExternalLinksController extends Controller { @@ -24,22 +26,26 @@ class CMSExternalLinksController extends Controller */ public function getJobStatus() { - // Set headers - HTTPCacheControlMiddleware::singleton()->setMaxAge(0); - $this->response - ->addHeader('Content-Type', 'application/json') - ->addHeader('Content-Encoding', 'UTF-8') - ->addHeader('X-Content-Type-Options', 'nosniff'); + if (Permission::checkMember(Security::getCurrentUser(), ['CMS_ACCESS_CMSMain'])) { + // Set headers + HTTPCacheControlMiddleware::singleton()->setMaxAge(0); + $this->response + ->addHeader('Content-Type', 'application/json') + ->addHeader('Content-Encoding', 'UTF-8') + ->addHeader('X-Content-Type-Options', 'nosniff'); - // Format status - $track = BrokenExternalPageTrackStatus::get_latest(); - if ($track) { - return json_encode([ - 'TrackID' => $track->ID, - 'Status' => $track->Status, - 'Completed' => $track->getCompletedPages(), - 'Total' => $track->getTotalPages() - ]); + // Format status + $track = BrokenExternalPageTrackStatus::get_latest(); + if ($track) { + return json_encode([ + 'TrackID' => $track->ID, + 'Status' => $track->Status, + 'Completed' => $track->getCompletedPages(), + 'Total' => $track->getTotalPages() + ]); + } + } else { + return $this->httpError(403, 'You do not have permission to access this resource'); } } @@ -49,24 +55,28 @@ public function getJobStatus() */ public function start() { - // return if the a job is already running - $status = BrokenExternalPageTrackStatus::get_latest(); - if ($status && $status->Status == 'Running') { - return; - } + if (Permission::checkMember(Security::getCurrentUser(), ['CMS_ACCESS_CMSMain'])) { + // return if the a job is already running + $status = BrokenExternalPageTrackStatus::get_latest(); + if ($status && $status->Status == 'Running') { + return; + } - // Create a new job - if (class_exists(QueuedJobService::class)) { - // Force the creation of a new run - BrokenExternalPageTrackStatus::create_status(); - $checkLinks = new CheckExternalLinksJob(); - singleton(QueuedJobService::class)->queueJob($checkLinks); + // Create a new job + if (class_exists(QueuedJobService::class)) { + // Force the creation of a new run + BrokenExternalPageTrackStatus::create_status(); + $checkLinks = new CheckExternalLinksJob(); + singleton(QueuedJobService::class)->queueJob($checkLinks); + } else { + //TODO this hangs as it waits for the connection to be released + // should return back and continue processing + // http://us3.php.net/manual/en/features.connection-handling.php + $task = CheckExternalLinksTask::create(); + $task->runLinksCheck(); + } } else { - //TODO this hangs as it waits for the connection to be released - // should return back and continue processing - // http://us3.php.net/manual/en/features.connection-handling.php - $task = CheckExternalLinksTask::create(); - $task->runLinksCheck(); + return $this->httpError(403, 'You do not have permission to access this resource'); } } } diff --git a/tests/php/ExternalLinksTest.php b/tests/php/ExternalLinksTest.php index 433ea5b..5dc0fa6 100644 --- a/tests/php/ExternalLinksTest.php +++ b/tests/php/ExternalLinksTest.php @@ -3,7 +3,7 @@ namespace SilverStripe\ExternalLinks\Tests; use SilverStripe\Core\Injector\Injector; -use SilverStripe\Dev\SapphireTest; +use SilverStripe\Dev\FunctionalTest; use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus; use SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport; use SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask; @@ -13,7 +13,7 @@ use SilverStripe\i18n\i18n; use SilverStripe\Reports\Report; -class ExternalLinksTest extends SapphireTest +class ExternalLinksTest extends FunctionalTest { protected static $fixture_file = 'ExternalLinksTest.yml'; @@ -125,4 +125,30 @@ public function testArchivedPagesAreHiddenFromReport() // Ensure report does not list the link associated with an archived page $this->assertEquals(3, BrokenExternalLinksReport::create()->sourceRecords()->count()); } + + public function getJobStatusDataProvider() + { + return [ + 'ADMIN - valid permission' => ['ADMIN', 200], + 'CMS_ACCESS_CMSMain - valid permission' => ['CMS_ACCESS_CMSMain', 200], + 'VIEW_SITE - not enough permission' => ['VIEW_SITE', 403], + ]; + } + + /** + * @dataProvider getJobStatusDataProvider + */ + public function testGetJobStatus( + string $permission, + int $expectedResponseCode + ) { + $this->logOut(); + $this->logInWithPermission($permission); + + $response = $this->get("admin/externallinks/start", null, ['Accept' => 'application/json']); + $this->assertEquals($expectedResponseCode, $response->getStatusCode()); + + $response = $this->get("admin/externallinks/getJobStatus", null, ['Accept' => 'application/json']); + $this->assertEquals($expectedResponseCode, $response->getStatusCode()); + } }