Pages: Redirect user to view if they can't edit

For #5568
This commit is contained in:
Dan Brown 2025-05-24 12:05:17 +01:00
parent b29fe5c46d
commit 454b152b95
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 17 additions and 6 deletions

View File

@ -17,6 +17,7 @@ use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditActivity; use BookStack\Entities\Tools\PageEditActivity;
use BookStack\Entities\Tools\PageEditorData; use BookStack\Entities\Tools\PageEditorData;
use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\NotifyException;
use BookStack\Exceptions\PermissionsException; use BookStack\Exceptions\PermissionsException;
use BookStack\Http\Controller; use BookStack\Http\Controller;
use BookStack\References\ReferenceFetcher; use BookStack\References\ReferenceFetcher;
@ -196,7 +197,7 @@ class PageController extends Controller
public function edit(Request $request, string $bookSlug, string $pageSlug) public function edit(Request $request, string $bookSlug, string $pageSlug)
{ {
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
$this->checkOwnablePermission('page-update', $page); $this->checkOwnablePermission('page-update', $page, $page->getUrl());
$editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', '')); $editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', ''));
if ($editorData->getWarnings()) { if ($editorData->getWarnings()) {

View File

@ -49,13 +49,13 @@ abstract class Controller extends BaseController
* On a permission error redirect to home and display. * On a permission error redirect to home and display.
* the error as a notification. * the error as a notification.
* *
* @return never * @throws NotifyException
*/ */
protected function showPermissionError() protected function showPermissionError(string $redirectLocation = '/'): never
{ {
$message = request()->wantsJson() ? trans('errors.permissionJson') : trans('errors.permission'); $message = request()->wantsJson() ? trans('errors.permissionJson') : trans('errors.permission');
throw new NotifyException($message, '/', 403); throw new NotifyException($message, $redirectLocation, 403);
} }
/** /**
@ -81,10 +81,10 @@ abstract class Controller extends BaseController
/** /**
* Check the current user's permissions against an ownable item otherwise throw an exception. * Check the current user's permissions against an ownable item otherwise throw an exception.
*/ */
protected function checkOwnablePermission(string $permission, Model $ownable): void protected function checkOwnablePermission(string $permission, Model $ownable, string $redirectLocation = '/'): void
{ {
if (!userCan($permission, $ownable)) { if (!userCan($permission, $ownable)) {
$this->showPermissionError(); $this->showPermissionError($redirectLocation);
} }
} }

View File

@ -356,4 +356,14 @@ class PageTest extends TestCase
$resp = $this->get('/'); $resp = $this->get('/');
$this->withHtml($resp)->assertElementContains('#recently-updated-pages', $page->name); $this->withHtml($resp)->assertElementContains('#recently-updated-pages', $page->name);
} }
public function test_page_edit_without_update_permissions_but_with_view_redirects_to_page()
{
$page = $this->entities->page();
$resp = $this->asViewer()->get($page->getUrl('/edit'));
$resp->assertRedirect($page->getUrl());
$resp->assertSessionHas('error', 'You do not have permission to access the requested page.');
}
} }