mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-10-12 02:01:37 +00:00
Page Drafts: Applied draft owner check to more endpoints
As a follow-up to e3068369a2, this applies
the draft ownership check to various other draft endpoints.
Thanks again to SVO for reporting.
This commit is contained in:
@@ -7,6 +7,7 @@ use BookStack\Activity\Tools\CommentTree;
|
||||
use BookStack\Activity\Tools\UserEntityWatchOptions;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Queries\EntityQueries;
|
||||
use BookStack\Entities\Queries\PageQueries;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
@@ -95,7 +96,7 @@ class PageController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show form to continue editing a draft page.
|
||||
* Show a form to continue editing a draft page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
@@ -103,6 +104,7 @@ class PageController extends Controller
|
||||
{
|
||||
$draft = $this->queries->findVisibleByIdOrFail($pageId);
|
||||
$this->checkOwnablePermission(Permission::PageCreate, $draft->getParent());
|
||||
$this->ensureDraftAccess($draft);
|
||||
|
||||
$editorData = new PageEditorData($draft, $this->entityQueries, $request->query('editor', ''));
|
||||
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
||||
@@ -124,6 +126,7 @@ class PageController extends Controller
|
||||
|
||||
$draftPage = $this->queries->findVisibleByIdOrFail($pageId);
|
||||
$this->checkOwnablePermission(Permission::PageCreate, $draftPage->getParent());
|
||||
$this->ensureDraftAccess($draftPage);
|
||||
|
||||
$page = $this->pageRepo->publishDraft($draftPage, $request->all());
|
||||
|
||||
@@ -235,6 +238,7 @@ class PageController extends Controller
|
||||
* Save a draft update as a revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws PermissionsException
|
||||
*/
|
||||
public function saveDraft(Request $request, int $pageId)
|
||||
{
|
||||
@@ -245,6 +249,10 @@ class PageController extends Controller
|
||||
return $this->jsonError(trans('errors.guests_cannot_save_drafts'), 500);
|
||||
}
|
||||
|
||||
if ($page->draft) {
|
||||
$this->ensureDraftAccess($page);
|
||||
}
|
||||
|
||||
$draft = $this->pageRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown']));
|
||||
$warnings = (new PageEditActivity($page))->getWarningMessagesForDraft($draft);
|
||||
|
||||
@@ -294,11 +302,14 @@ class PageController extends Controller
|
||||
* Show the deletion page for the specified page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws PermissionsException
|
||||
*/
|
||||
public function showDeleteDraft(string $bookSlug, int $pageId)
|
||||
{
|
||||
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
||||
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||
$this->ensureDraftAccess($page);
|
||||
|
||||
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()]));
|
||||
$usedAsTemplate =
|
||||
$this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
|
||||
@@ -340,7 +351,9 @@ class PageController extends Controller
|
||||
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
||||
$book = $page->book;
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||
$this->ensureDraftAccess($page);
|
||||
|
||||
$this->pageRepo->destroy($page);
|
||||
|
||||
@@ -470,4 +483,14 @@ class PageController extends Controller
|
||||
|
||||
return redirect($pageCopy->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PermissionsException
|
||||
*/
|
||||
protected function ensureDraftAccess(Page $draft): void
|
||||
{
|
||||
if (!$draft->draft || $draft->created_by !== user()->id) {
|
||||
throw new PermissionsException('This page is already published or does not belong to you.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +82,6 @@ class PageRepo
|
||||
*/
|
||||
public function publishDraft(Page $draft, array $input): Page
|
||||
{
|
||||
if (!$draft->draft || $draft->created_by !== user()->id) {
|
||||
throw new PermissionsException('This page is already published or does not belong to you.');
|
||||
}
|
||||
|
||||
return (new DatabaseTransaction(function () use ($draft, $input) {
|
||||
$draft->draft = false;
|
||||
$draft->revision_count = 1;
|
||||
|
||||
@@ -153,7 +153,7 @@ class ImageController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Check related page permission and ensure type is drawio or gallery.
|
||||
* Check related page permission and ensure the type is drawio or gallery.
|
||||
* @throws NotifyException
|
||||
*/
|
||||
protected function checkImagePermission(Image $image): void
|
||||
|
||||
@@ -245,7 +245,7 @@ class PageDraftTest extends TestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_draft_published_can_only_be_used_on_draft_pages()
|
||||
public function test_draft_publish_can_only_be_used_on_draft_pages()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$this->withoutExceptionHandling();
|
||||
@@ -263,4 +263,27 @@ class PageDraftTest extends TestCase
|
||||
$page->refresh();
|
||||
$this->assertNotEquals('My published drafty', $page->name);
|
||||
}
|
||||
|
||||
public function test_destroy_draft_can_only_be_used_on_draft_pages()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$this->withoutExceptionHandling();
|
||||
|
||||
$exception = null;
|
||||
try {
|
||||
$this->asEditor()->delete($page->book->getUrl("/draft/{$page->id}"));
|
||||
} catch (\Exception $e) {
|
||||
$exception = $e;
|
||||
}
|
||||
|
||||
$this->assertInstanceOf(PermissionsException::class, $exception);
|
||||
$this->assertStringContainsString('This page is already published or does not belong to you', $exception->getMessage());
|
||||
|
||||
$page->refresh();
|
||||
$this->assertDatabaseHas('entities', [
|
||||
'id' => $page->id,
|
||||
'type' => 'page',
|
||||
'deleted_at' => null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user