From 2bcc159fd6f51b9f18520f76888a81d46934f24f Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 14 Jul 2018 14:12:29 +0100 Subject: [PATCH] Allowed creating pages in visible chapters in invisible books Fixes permissions with test to cover in the event a page is created, with permission, in a chapter but the user does not have permission to see the parent book. Fixes #912 --- app/Http/Controllers/PageController.php | 32 ++++++++++++++++--------- app/Page.php | 9 +++++++ tests/Permissions/RestrictionsTest.php | 22 +++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 221e21a99..25a0503eb 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -5,7 +5,6 @@ use BookStack\Exceptions\NotFoundException; use BookStack\Repos\EntityRepo; use BookStack\Repos\UserRepo; use BookStack\Services\ExportService; -use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Http\Response; use Views; @@ -38,11 +37,18 @@ class PageController extends Controller * @param string $chapterSlug * @return Response * @internal param bool $pageSlug + * @throws NotFoundException */ public function create($bookSlug, $chapterSlug = null) { - $book = $this->entityRepo->getBySlug('book', $bookSlug); - $chapter = $chapterSlug ? $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug) : null; + if ($chapterSlug !== null) { + $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); + $book = $chapter->book; + } else { + $chapter = null; + $book = $this->entityRepo->getBySlug('book', $bookSlug); + } + $parent = $chapter ? $chapter : $book; $this->checkOwnablePermission('page-create', $parent); @@ -52,7 +58,7 @@ class PageController extends Controller return redirect($draft->getUrl()); } - // Otherwise show edit view + // Otherwise show the edit view if they're a guest $this->setPageTitle(trans('entities.pages_new')); return view('pages/guest-create', ['parent' => $parent]); } @@ -71,8 +77,14 @@ class PageController extends Controller 'name' => 'required|string|max:255' ]); - $book = $this->entityRepo->getBySlug('book', $bookSlug); - $chapter = $chapterSlug ? $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug) : null; + if ($chapterSlug !== null) { + $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); + $book = $chapter->book; + } else { + $chapter = null; + $book = $this->entityRepo->getBySlug('book', $bookSlug); + } + $parent = $chapter ? $chapter : $book; $this->checkOwnablePermission('page-create', $parent); @@ -93,7 +105,7 @@ class PageController extends Controller public function editDraft($bookSlug, $pageId) { $draft = $this->entityRepo->getById('page', $pageId, true); - $this->checkOwnablePermission('page-create', $draft->book); + $this->checkOwnablePermission('page-create', $draft->parent); $this->setPageTitle(trans('entities.pages_edit_draft')); $draftsEnabled = $this->signedIn; @@ -119,12 +131,10 @@ class PageController extends Controller ]); $input = $request->all(); - $book = $this->entityRepo->getBySlug('book', $bookSlug); - $draftPage = $this->entityRepo->getById('page', $pageId, true); + $book = $draftPage->book; - $chapterId = intval($draftPage->chapter_id); - $parent = $chapterId !== 0 ? $this->entityRepo->getById('chapter', $chapterId) : $book; + $parent = $draftPage->parent; $this->checkOwnablePermission('page-create', $parent); if ($parent->isA('chapter')) { diff --git a/app/Page.php b/app/Page.php index 38feb610d..9554504b3 100644 --- a/app/Page.php +++ b/app/Page.php @@ -28,6 +28,15 @@ class Page extends Entity return $this->belongsTo(Book::class); } + /** + * Get the parent item + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function parent() + { + return $this->chapter_id ? $this->chapter() : $this->book(); + } + /** * Get the chapter that this page is in, If applicable. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/tests/Permissions/RestrictionsTest.php b/tests/Permissions/RestrictionsTest.php index 53e7ad3f3..2bbb1a5fa 100644 --- a/tests/Permissions/RestrictionsTest.php +++ b/tests/Permissions/RestrictionsTest.php @@ -592,4 +592,26 @@ class RestrictionsTest extends BrowserKitTest ->see('You do not have permission') ->seePageIs('/'); } + + public function test_can_create_page_if_chapter_has_permissions_when_book_not_visible() + { + $book = Book::first(); + $this->setEntityRestrictions($book, []); + $bookChapter = $book->chapters->first(); + $this->setEntityRestrictions($bookChapter, ['view']); + + $this->actingAs($this->user)->visit($bookChapter->getUrl()) + ->dontSee('New Page'); + + $this->setEntityRestrictions($bookChapter, ['view', 'create']); + + $this->actingAs($this->user)->visit($bookChapter->getUrl()) + ->click('New Page') + ->seeStatusCode(200) + ->type('test page', 'name') + ->type('test content', 'html') + ->press('Save Page') + ->seePageIs($book->getUrl('/page/test-page')) + ->seeStatusCode(200); + } }