From b662670efcb2ee481ff47f11c426bb474af0b901 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Thu, 29 Sep 2016 15:56:57 +0100
Subject: [PATCH] Prevented guest users creating draft pages.

---
 app/Http/Controllers/PageController.php      | 59 ++++++++++++++++++--
 resources/assets/js/controllers.js           |  4 +-
 resources/views/pages/edit.blade.php         |  6 --
 resources/views/pages/form.blade.php         | 13 ++++-
 resources/views/pages/guest-create.blade.php | 25 +++++++++
 routes/web.php                               |  2 +
 6 files changed, 93 insertions(+), 16 deletions(-)
 create mode 100644 resources/views/pages/guest-create.blade.php

diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php
index 033377a4d..f4cbd33ea 100644
--- a/app/Http/Controllers/PageController.php
+++ b/app/Http/Controllers/PageController.php
@@ -44,20 +44,53 @@ class PageController extends Controller
     /**
      * Show the form for creating a new page.
      * @param string $bookSlug
-     * @param bool $chapterSlug
+     * @param string $chapterSlug
      * @return Response
      * @internal param bool $pageSlug
      */
-    public function create($bookSlug, $chapterSlug = false)
+    public function create($bookSlug, $chapterSlug = null)
     {
         $book = $this->bookRepo->getBySlug($bookSlug);
         $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : null;
         $parent = $chapter ? $chapter : $book;
         $this->checkOwnablePermission('page-create', $parent);
-        $this->setPageTitle('Create New Page');
 
-        $draft = $this->pageRepo->getDraftPage($book, $chapter);
-        return redirect($draft->getUrl());
+        // Redirect to draft edit screen if signed in
+        if ($this->signedIn) {
+            $draft = $this->pageRepo->getDraftPage($book, $chapter);
+            return redirect($draft->getUrl());
+        }
+
+        // Otherwise show edit view
+        $this->setPageTitle('Create New Page');
+        return view('pages/guest-create', ['parent' => $parent]);
+    }
+
+    /**
+     * Create a new page as a guest user.
+     * @param Request $request
+     * @param string $bookSlug
+     * @param string|null $chapterSlug
+     * @return mixed
+     * @throws NotFoundException
+     */
+    public function createAsGuest(Request $request, $bookSlug, $chapterSlug = null)
+    {
+        $this->validate($request, [
+            'name' => 'required|string|max:255'
+        ]);
+
+        $book = $this->bookRepo->getBySlug($bookSlug);
+        $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : null;
+        $parent = $chapter ? $chapter : $book;
+        $this->checkOwnablePermission('page-create', $parent);
+
+        $page = $this->pageRepo->getDraftPage($book, $chapter);
+        $this->pageRepo->publishDraft($page, [
+            'name' => $request->get('name'),
+            'html' => ''
+        ]);
+        return redirect($page->getUrl('/edit'));
     }
 
     /**
@@ -183,7 +216,13 @@ class PageController extends Controller
 
         if (count($warnings) > 0) session()->flash('warning', implode("\n", $warnings));
 
-        return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]);
+        $draftsEnabled = $this->signedIn;
+        return view('pages/edit', [
+            'page' => $page,
+            'book' => $book,
+            'current' => $page,
+            'draftsEnabled' => $draftsEnabled
+        ]);
     }
 
     /**
@@ -216,6 +255,14 @@ class PageController extends Controller
     {
         $page = $this->pageRepo->getById($pageId, true);
         $this->checkOwnablePermission('page-update', $page);
+
+        if (!$this->signedIn) {
+            return response()->json([
+                'status' => 'error',
+                'message' => 'Guests cannot save drafts',
+            ], 500);
+        }
+
         if ($page->draft) {
             $draft = $this->pageRepo->updateDraftPage($page, $request->only(['name', 'html', 'markdown']));
         } else {
diff --git a/resources/assets/js/controllers.js b/resources/assets/js/controllers.js
index 2c0cf3e2b..a64bdfa8c 100644
--- a/resources/assets/js/controllers.js
+++ b/resources/assets/js/controllers.js
@@ -300,6 +300,7 @@ module.exports = function (ngApp, events) {
         var isEdit = pageId !== 0;
         var autosaveFrequency = 30; // AutoSave interval in seconds.
         var isMarkdown = $attrs.editorType === 'markdown';
+        $scope.draftsEnabled = $attrs.draftsEnabled === 'true';
         $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1;
         $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1;
 
@@ -317,7 +318,7 @@ module.exports = function (ngApp, events) {
             html: false
         };
 
-        if (isEdit) {
+        if (isEdit && $scope.draftsEnabled) {
             setTimeout(() => {
                 startAutoSave();
             }, 1000);
@@ -366,6 +367,7 @@ module.exports = function (ngApp, events) {
          * Save a draft update into the system via an AJAX request.
          */
         function saveDraft() {
+            if (!$scope.draftsEnabled) return;
             var data = {
                 name: $('#name').val(),
                 html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent
diff --git a/resources/views/pages/edit.blade.php b/resources/views/pages/edit.blade.php
index d39e24e92..e50cc7c5b 100644
--- a/resources/views/pages/edit.blade.php
+++ b/resources/views/pages/edit.blade.php
@@ -23,10 +23,4 @@
     @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id])
     @include('partials/entity-selector-popup')
 
-    <script>
-        (function() {
-
-        })();
-    </script>
-
 @stop
\ No newline at end of file
diff --git a/resources/views/pages/form.blade.php b/resources/views/pages/form.blade.php
index 0e0c3672e..c4baf38f7 100644
--- a/resources/views/pages/form.blade.php
+++ b/resources/views/pages/form.blade.php
@@ -1,7 +1,9 @@
 
-<div class="page-editor flex-fill flex" ng-controller="PageEditController" editor-type="{{ setting('app-editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}">
+<div class="page-editor flex-fill flex" ng-controller="PageEditController" drafts-enabled="{{ $draftsEnabled ? 'true' : 'false' }}" editor-type="{{ setting('app-editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}">
 
     {{ csrf_field() }}
+
+    {{--Header Bar--}}
     <div class="faded-small toolbar">
         <div class="container">
             <div class="row">
@@ -13,7 +15,7 @@
                 </div>
                 <div class="col-sm-4 faded text-center">
 
-                    <div dropdown class="dropdown-container draft-display">
+                    <div ng-show="draftsEnabled" dropdown class="dropdown-container draft-display">
                         <a dropdown-toggle class="text-primary text-button"><span class="faded-text" ng-bind="draftText"></span>&nbsp; <i class="zmdi zmdi-more-vert"></i></a>
                         <i class="zmdi zmdi-check-circle text-pos draft-notification" ng-class="{visible: draftUpdated}"></i>
                         <ul>
@@ -48,13 +50,17 @@
         </div>
     </div>
 
+    {{--Title input--}}
     <div class="title-input page-title clearfix" ng-non-bindable>
         <div class="input">
             @include('form/text', ['name' => 'name', 'placeholder' => 'Page Title'])
         </div>
     </div>
 
+    {{--Editors--}}
     <div class="edit-area flex-fill flex">
+
+        {{--WYSIWYG Editor--}}
         @if(setting('app-editor') === 'wysiwyg')
             <div tinymce="editorOptions" mce-change="editorChange" mce-model="editContent" class="flex-fill flex">
                 <textarea id="html-editor"   name="html" rows="5" ng-non-bindable
@@ -66,6 +72,7 @@
             @endif
         @endif
 
+        {{--Markdown Editor--}}
         @if(setting('app-editor') === 'markdown')
             <div id="markdown-editor" markdown-editor class="flex-fill flex">
 
@@ -102,7 +109,7 @@
             @if($errors->has('markdown'))
                 <div class="text-neg text-small">{{ $errors->first('markdown') }}</div>
             @endif
-
         @endif
+
     </div>
 </div>
\ No newline at end of file
diff --git a/resources/views/pages/guest-create.blade.php b/resources/views/pages/guest-create.blade.php
new file mode 100644
index 000000000..00d9f5560
--- /dev/null
+++ b/resources/views/pages/guest-create.blade.php
@@ -0,0 +1,25 @@
+@extends('base')
+
+@section('content')
+
+    <div class="container small" ng-non-bindable>
+        <h1>Create Page</h1>
+        <form action="{{  $parent->getUrl('/page/create/guest') }}" method="POST">
+
+            {!! csrf_field() !!}
+
+            <div class="form-group title-input">
+                <label for="name">Page Name</label>
+                @include('form/text', ['name' => 'name'])
+            </div>
+
+            <div class="form-group">
+                <a href="{{ $parent->getUrl() }}" class="button muted">Cancel</a>
+                <button type="submit" class="button pos">Continue</button>
+            </div>
+
+        </form>
+    </div>
+
+
+@stop
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index c3fe503d1..19541734b 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -27,6 +27,7 @@ Route::group(['middleware' => 'auth'], function () {
 
         // Pages
         Route::get('/{bookSlug}/page/create', 'PageController@create');
+        Route::post('/{bookSlug}/page/create/guest', 'PageController@createAsGuest');
         Route::get('/{bookSlug}/draft/{pageId}', 'PageController@editDraft');
         Route::post('/{bookSlug}/draft/{pageId}', 'PageController@store');
         Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show');
@@ -52,6 +53,7 @@ Route::group(['middleware' => 'auth'], function () {
 
         // Chapters
         Route::get('/{bookSlug}/chapter/{chapterSlug}/create-page', 'PageController@create');
+        Route::post('/{bookSlug}/chapter/{chapterSlug}/page/create/guest', 'PageController@createAsGuest');
         Route::get('/{bookSlug}/chapter/create', 'ChapterController@create');
         Route::post('/{bookSlug}/chapter/create', 'ChapterController@store');
         Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show');