Dan Brown

Implemented database structure and inital interfaces for entity restrictions

...@@ -48,7 +48,6 @@ abstract class Entity extends Ownable ...@@ -48,7 +48,6 @@ abstract class Entity extends Ownable
48 48
49 /** 49 /**
50 * Get View objects for this entity. 50 * Get View objects for this entity.
51 - * @return mixed
52 */ 51 */
53 public function views() 52 public function views()
54 { 53 {
...@@ -56,6 +55,25 @@ abstract class Entity extends Ownable ...@@ -56,6 +55,25 @@ abstract class Entity extends Ownable
56 } 55 }
57 56
58 /** 57 /**
58 + * Get this entities restrictions.
59 + */
60 + public function restrictions()
61 + {
62 + return $this->morphMany('BookStack\Restriction', 'restrictable');
63 + }
64 +
65 + /**
66 + * Check if this entity has a specific restriction set against it.
67 + * @param $role_id
68 + * @param $action
69 + * @return bool
70 + */
71 + public function hasRestriction($role_id, $action)
72 + {
73 + return $this->restrictions->where('role_id', $role_id)->where('action', $action)->count() > 0;
74 + }
75 +
76 + /**
59 * Allows checking of the exact class, Used to check entity type. 77 * Allows checking of the exact class, Used to check entity type.
60 * Cleaner method for is_a. 78 * Cleaner method for is_a.
61 * @param $type 79 * @param $type
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
3 namespace BookStack\Http\Controllers; 3 namespace BookStack\Http\Controllers;
4 4
5 use Activity; 5 use Activity;
6 +use BookStack\Repos\UserRepo;
6 use Illuminate\Http\Request; 7 use Illuminate\Http\Request;
7 8
8 use Illuminate\Support\Facades\Auth; 9 use Illuminate\Support\Facades\Auth;
...@@ -19,18 +20,21 @@ class BookController extends Controller ...@@ -19,18 +20,21 @@ class BookController extends Controller
19 protected $bookRepo; 20 protected $bookRepo;
20 protected $pageRepo; 21 protected $pageRepo;
21 protected $chapterRepo; 22 protected $chapterRepo;
23 + protected $userRepo;
22 24
23 /** 25 /**
24 * BookController constructor. 26 * BookController constructor.
25 * @param BookRepo $bookRepo 27 * @param BookRepo $bookRepo
26 * @param PageRepo $pageRepo 28 * @param PageRepo $pageRepo
27 * @param ChapterRepo $chapterRepo 29 * @param ChapterRepo $chapterRepo
30 + * @param UserRepo $userRepo
28 */ 31 */
29 - public function __construct(BookRepo $bookRepo, PageRepo $pageRepo, ChapterRepo $chapterRepo) 32 + public function __construct(BookRepo $bookRepo, PageRepo $pageRepo, ChapterRepo $chapterRepo, UserRepo $userRepo)
30 { 33 {
31 $this->bookRepo = $bookRepo; 34 $this->bookRepo = $bookRepo;
32 $this->pageRepo = $pageRepo; 35 $this->pageRepo = $pageRepo;
33 $this->chapterRepo = $chapterRepo; 36 $this->chapterRepo = $chapterRepo;
37 + $this->userRepo = $userRepo;
34 parent::__construct(); 38 parent::__construct();
35 } 39 }
36 40
...@@ -177,7 +181,6 @@ class BookController extends Controller ...@@ -177,7 +181,6 @@ class BookController extends Controller
177 181
178 /** 182 /**
179 * Saves an array of sort mapping to pages and chapters. 183 * Saves an array of sort mapping to pages and chapters.
180 - *
181 * @param string $bookSlug 184 * @param string $bookSlug
182 * @param Request $request 185 * @param Request $request
183 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector 186 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
...@@ -223,7 +226,6 @@ class BookController extends Controller ...@@ -223,7 +226,6 @@ class BookController extends Controller
223 226
224 /** 227 /**
225 * Remove the specified book from storage. 228 * Remove the specified book from storage.
226 - *
227 * @param $bookSlug 229 * @param $bookSlug
228 * @return Response 230 * @return Response
229 */ 231 */
...@@ -236,4 +238,36 @@ class BookController extends Controller ...@@ -236,4 +238,36 @@ class BookController extends Controller
236 $this->bookRepo->destroyBySlug($bookSlug); 238 $this->bookRepo->destroyBySlug($bookSlug);
237 return redirect('/books'); 239 return redirect('/books');
238 } 240 }
241 +
242 + /**
243 + * Show the Restrictions view.
244 + * @param $bookSlug
245 + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
246 + */
247 + public function showRestrict($bookSlug)
248 + {
249 + $book = $this->bookRepo->getBySlug($bookSlug);
250 + $this->checkOwnablePermission('restrictions-manage', $book);
251 + $roles = $this->userRepo->getRestrictableRoles();
252 + return view('books/restrictions', [
253 + 'book' => $book,
254 + 'roles' => $roles
255 + ]);
256 + }
257 +
258 + /**
259 + * Set the restrictions for this book.
260 + * @param $bookSlug
261 + * @param $bookSlug
262 + * @param Request $request
263 + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
264 + */
265 + public function restrict($bookSlug, Request $request)
266 + {
267 + $book = $this->bookRepo->getBySlug($bookSlug);
268 + $this->checkOwnablePermission('restrictions-manage', $book);
269 + $this->bookRepo->updateRestrictionsFromRequest($request, $book);
270 + session()->flash('success', 'Page Restrictions Updated');
271 + return redirect($book->getUrl());
272 + }
239 } 273 }
......
1 <?php namespace BookStack\Http\Controllers; 1 <?php namespace BookStack\Http\Controllers;
2 2
3 use Activity; 3 use Activity;
4 +use BookStack\Repos\UserRepo;
4 use Illuminate\Http\Request; 5 use Illuminate\Http\Request;
5 use BookStack\Http\Requests; 6 use BookStack\Http\Requests;
6 use BookStack\Repos\BookRepo; 7 use BookStack\Repos\BookRepo;
...@@ -12,16 +13,19 @@ class ChapterController extends Controller ...@@ -12,16 +13,19 @@ class ChapterController extends Controller
12 13
13 protected $bookRepo; 14 protected $bookRepo;
14 protected $chapterRepo; 15 protected $chapterRepo;
16 + protected $userRepo;
15 17
16 /** 18 /**
17 * ChapterController constructor. 19 * ChapterController constructor.
18 - * @param $bookRepo 20 + * @param BookRepo $bookRepo
19 - * @param $chapterRepo 21 + * @param ChapterRepo $chapterRepo
22 + * @param UserRepo $userRepo
20 */ 23 */
21 - public function __construct(BookRepo $bookRepo, ChapterRepo $chapterRepo) 24 + public function __construct(BookRepo $bookRepo, ChapterRepo $chapterRepo, UserRepo $userRepo)
22 { 25 {
23 $this->bookRepo = $bookRepo; 26 $this->bookRepo = $bookRepo;
24 $this->chapterRepo = $chapterRepo; 27 $this->chapterRepo = $chapterRepo;
28 + $this->userRepo = $userRepo;
25 parent::__construct(); 29 parent::__construct();
26 } 30 }
27 31
...@@ -144,4 +148,39 @@ class ChapterController extends Controller ...@@ -144,4 +148,39 @@ class ChapterController extends Controller
144 $this->chapterRepo->destroy($chapter); 148 $this->chapterRepo->destroy($chapter);
145 return redirect($book->getUrl()); 149 return redirect($book->getUrl());
146 } 150 }
151 +
152 + /**
153 + * Show the Restrictions view.
154 + * @param $bookSlug
155 + * @param $chapterSlug
156 + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
157 + */
158 + public function showRestrict($bookSlug, $chapterSlug)
159 + {
160 + $book = $this->bookRepo->getBySlug($bookSlug);
161 + $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
162 + $this->checkOwnablePermission('restrictions-manage', $chapter);
163 + $roles = $this->userRepo->getRestrictableRoles();
164 + return view('chapters/restrictions', [
165 + 'chapter' => $chapter,
166 + 'roles' => $roles
167 + ]);
168 + }
169 +
170 + /**
171 + * Set the restrictions for this chapter.
172 + * @param $bookSlug
173 + * @param $chapterSlug
174 + * @param Request $request
175 + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
176 + */
177 + public function restrict($bookSlug, $chapterSlug, Request $request)
178 + {
179 + $book = $this->bookRepo->getBySlug($bookSlug);
180 + $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
181 + $this->checkOwnablePermission('restrictions-manage', $chapter);
182 + $this->chapterRepo->updateRestrictionsFromRequest($request, $chapter);
183 + session()->flash('success', 'Page Restrictions Updated');
184 + return redirect($chapter->getUrl());
185 + }
147 } 186 }
......
1 <?php namespace BookStack\Http\Controllers; 1 <?php namespace BookStack\Http\Controllers;
2 2
3 use Activity; 3 use Activity;
4 +use BookStack\Repos\UserRepo;
4 use BookStack\Services\ExportService; 5 use BookStack\Services\ExportService;
5 use Illuminate\Http\Request; 6 use Illuminate\Http\Request;
6 use BookStack\Http\Requests; 7 use BookStack\Http\Requests;
...@@ -17,20 +18,23 @@ class PageController extends Controller ...@@ -17,20 +18,23 @@ class PageController extends Controller
17 protected $bookRepo; 18 protected $bookRepo;
18 protected $chapterRepo; 19 protected $chapterRepo;
19 protected $exportService; 20 protected $exportService;
21 + protected $userRepo;
20 22
21 /** 23 /**
22 * PageController constructor. 24 * PageController constructor.
23 - * @param PageRepo $pageRepo 25 + * @param PageRepo $pageRepo
24 - * @param BookRepo $bookRepo 26 + * @param BookRepo $bookRepo
25 - * @param ChapterRepo $chapterRepo 27 + * @param ChapterRepo $chapterRepo
26 * @param ExportService $exportService 28 * @param ExportService $exportService
29 + * @param UserRepo $userRepo
27 */ 30 */
28 - public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, ExportService $exportService) 31 + public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, ExportService $exportService, UserRepo $userRepo)
29 { 32 {
30 $this->pageRepo = $pageRepo; 33 $this->pageRepo = $pageRepo;
31 $this->bookRepo = $bookRepo; 34 $this->bookRepo = $bookRepo;
32 $this->chapterRepo = $chapterRepo; 35 $this->chapterRepo = $chapterRepo;
33 $this->exportService = $exportService; 36 $this->exportService = $exportService;
37 + $this->userRepo = $userRepo;
34 parent::__construct(); 38 parent::__construct();
35 } 39 }
36 40
...@@ -308,4 +312,39 @@ class PageController extends Controller ...@@ -308,4 +312,39 @@ class PageController extends Controller
308 ]); 312 ]);
309 } 313 }
310 314
315 + /**
316 + * Show the Restrictions view.
317 + * @param $bookSlug
318 + * @param $pageSlug
319 + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
320 + */
321 + public function showRestrict($bookSlug, $pageSlug)
322 + {
323 + $book = $this->bookRepo->getBySlug($bookSlug);
324 + $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
325 + $this->checkOwnablePermission('restrictions-manage', $page);
326 + $roles = $this->userRepo->getRestrictableRoles();
327 + return view('pages/restrictions', [
328 + 'page' => $page,
329 + 'roles' => $roles
330 + ]);
331 + }
332 +
333 + /**
334 + * Set the restrictions for this page.
335 + * @param $bookSlug
336 + * @param $pageSlug
337 + * @param Request $request
338 + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
339 + */
340 + public function restrict($bookSlug, $pageSlug, Request $request)
341 + {
342 + $book = $this->bookRepo->getBySlug($bookSlug);
343 + $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
344 + $this->checkOwnablePermission('restrictions-manage', $page);
345 + $this->pageRepo->updateRestrictionsFromRequest($request, $page);
346 + session()->flash('success', 'Page Restrictions Updated');
347 + return redirect($page->getUrl());
348 + }
349 +
311 } 350 }
......
...@@ -19,6 +19,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -19,6 +19,8 @@ Route::group(['middleware' => 'auth'], function () {
19 Route::delete('/{id}', 'BookController@destroy'); 19 Route::delete('/{id}', 'BookController@destroy');
20 Route::get('/{slug}/sort-item', 'BookController@getSortItem'); 20 Route::get('/{slug}/sort-item', 'BookController@getSortItem');
21 Route::get('/{slug}', 'BookController@show'); 21 Route::get('/{slug}', 'BookController@show');
22 + Route::get('/{bookSlug}/restrict', 'BookController@showRestrict');
23 + Route::put('/{bookSlug}/restrict', 'BookController@restrict');
22 Route::get('/{slug}/delete', 'BookController@showDelete'); 24 Route::get('/{slug}/delete', 'BookController@showDelete');
23 Route::get('/{bookSlug}/sort', 'BookController@sort'); 25 Route::get('/{bookSlug}/sort', 'BookController@sort');
24 Route::put('/{bookSlug}/sort', 'BookController@saveSort'); 26 Route::put('/{bookSlug}/sort', 'BookController@saveSort');
...@@ -32,6 +34,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -32,6 +34,8 @@ Route::group(['middleware' => 'auth'], function () {
32 Route::get('/{bookSlug}/page/{pageSlug}/export/plaintext', 'PageController@exportPlainText'); 34 Route::get('/{bookSlug}/page/{pageSlug}/export/plaintext', 'PageController@exportPlainText');
33 Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit'); 35 Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
34 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete'); 36 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
37 + Route::get('/{bookSlug}/page/{pageSlug}/restrict', 'PageController@showRestrict');
38 + Route::put('/{bookSlug}/page/{pageSlug}/restrict', 'PageController@restrict');
35 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update'); 39 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
36 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy'); 40 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy');
37 41
...@@ -47,6 +51,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -47,6 +51,8 @@ Route::group(['middleware' => 'auth'], function () {
47 Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show'); 51 Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show');
48 Route::put('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@update'); 52 Route::put('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@update');
49 Route::get('/{bookSlug}/chapter/{chapterSlug}/edit', 'ChapterController@edit'); 53 Route::get('/{bookSlug}/chapter/{chapterSlug}/edit', 'ChapterController@edit');
54 + Route::get('/{bookSlug}/chapter/{chapterSlug}/restrict', 'ChapterController@showRestrict');
55 + Route::put('/{bookSlug}/chapter/{chapterSlug}/restrict', 'ChapterController@restrict');
50 Route::get('/{bookSlug}/chapter/{chapterSlug}/delete', 'ChapterController@showDelete'); 56 Route::get('/{bookSlug}/chapter/{chapterSlug}/delete', 'ChapterController@showDelete');
51 Route::delete('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@destroy'); 57 Route::delete('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@destroy');
52 58
......
...@@ -238,4 +238,27 @@ class BookRepo ...@@ -238,4 +238,27 @@ class BookRepo
238 return $books; 238 return $books;
239 } 239 }
240 240
241 + /**
242 + * Updates books restrictions from a request
243 + * @param $request
244 + * @param $book
245 + */
246 + public function updateRestrictionsFromRequest($request, $book)
247 + {
248 + // TODO - extract into shared repo
249 + $book->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
250 + $book->restrictions()->delete();
251 + if ($request->has('restrictions')) {
252 + foreach($request->get('restrictions') as $roleId => $restrictions) {
253 + foreach ($restrictions as $action => $value) {
254 + $book->restrictions()->create([
255 + 'role_id' => $roleId,
256 + 'action' => strtolower($action)
257 + ]);
258 + }
259 + }
260 + }
261 + $book->save();
262 + }
263 +
241 } 264 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -161,4 +161,27 @@ class ChapterRepo ...@@ -161,4 +161,27 @@ class ChapterRepo
161 return $chapter; 161 return $chapter;
162 } 162 }
163 163
164 + /**
165 + * Updates pages restrictions from a request
166 + * @param $request
167 + * @param $chapter
168 + */
169 + public function updateRestrictionsFromRequest($request, $chapter)
170 + {
171 + // TODO - extract into shared repo
172 + $chapter->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
173 + $chapter->restrictions()->delete();
174 + if ($request->has('restrictions')) {
175 + foreach($request->get('restrictions') as $roleId => $restrictions) {
176 + foreach ($restrictions as $action => $value) {
177 + $chapter->restrictions()->create([
178 + 'role_id' => $roleId,
179 + 'action' => strtolower($action)
180 + ]);
181 + }
182 + }
183 + }
184 + $chapter->save();
185 + }
186 +
164 } 187 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -407,4 +407,27 @@ class PageRepo ...@@ -407,4 +407,27 @@ class PageRepo
407 return $this->page->orderBy('updated_at', 'desc')->paginate($count); 407 return $this->page->orderBy('updated_at', 'desc')->paginate($count);
408 } 408 }
409 409
410 + /**
411 + * Updates pages restrictions from a request
412 + * @param $request
413 + * @param $page
414 + */
415 + public function updateRestrictionsFromRequest($request, $page)
416 + {
417 + // TODO - extract into shared repo
418 + $page->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
419 + $page->restrictions()->delete();
420 + if ($request->has('restrictions')) {
421 + foreach($request->get('restrictions') as $roleId => $restrictions) {
422 + foreach ($restrictions as $action => $value) {
423 + $page->restrictions()->create([
424 + 'role_id' => $roleId,
425 + 'action' => strtolower($action)
426 + ]);
427 + }
428 + }
429 + }
430 + $page->save();
431 + }
432 +
410 } 433 }
......
...@@ -164,4 +164,14 @@ class UserRepo ...@@ -164,4 +164,14 @@ class UserRepo
164 ]; 164 ];
165 } 165 }
166 166
167 + /**
168 + * Get all the roles which can be given restricted access to
169 + * other entities in the system.
170 + * @return mixed
171 + */
172 + public function getRestrictableRoles()
173 + {
174 + return $this->role->where('name', '!=', 'admin')->get();
175 + }
176 +
167 } 177 }
...\ No newline at end of file ...\ No newline at end of file
......
1 +<?php
2 +
3 +namespace BookStack;
4 +
5 +use Illuminate\Database\Eloquent\Model;
6 +
7 +class Restriction extends Model
8 +{
9 +
10 + protected $fillable = ['role_id', 'action'];
11 + public $timestamps = false;
12 +
13 + /**
14 + * Get all this restriction's attached entity.
15 + * @return \Illuminate\Database\Eloquent\Relations\MorphTo
16 + */
17 + public function restrictable()
18 + {
19 + return $this->morphTo();
20 + }
21 +}
...@@ -26,7 +26,9 @@ class UpdatePermissionsAndRoles extends Migration ...@@ -26,7 +26,9 @@ class UpdatePermissionsAndRoles extends Migration
26 $permissionsToCreate = [ 26 $permissionsToCreate = [
27 'settings-manage' => 'Manage Settings', 27 'settings-manage' => 'Manage Settings',
28 'users-manage' => 'Manage Users', 28 'users-manage' => 'Manage Users',
29 - 'user-roles-manage' => 'Manage Roles & Permissions' 29 + 'user-roles-manage' => 'Manage Roles & Permissions',
30 + 'restrictions-manage-all' => 'Manage All Entity Restrictions',
31 + 'restrictions-manage-own' => 'Manage Entity Restrictions On Own Content'
30 ]; 32 ];
31 foreach ($permissionsToCreate as $name => $displayName) { 33 foreach ($permissionsToCreate as $name => $displayName) {
32 $newPermission = new \BookStack\Permission(); 34 $newPermission = new \BookStack\Permission();
......
1 +<?php
2 +
3 +use Illuminate\Database\Schema\Blueprint;
4 +use Illuminate\Database\Migrations\Migration;
5 +
6 +class AddEntityAccessControls extends Migration
7 +{
8 + /**
9 + * Run the migrations.
10 + *
11 + * @return void
12 + */
13 + public function up()
14 + {
15 + Schema::table('images', function (Blueprint $table) {
16 + $table->integer('uploaded_to')->default(0);
17 + $table->index('uploaded_to');
18 + });
19 +
20 + Schema::table('books', function (Blueprint $table) {
21 + $table->boolean('restricted')->default(false);
22 + $table->index('restricted');
23 + });
24 +
25 + Schema::table('chapters', function (Blueprint $table) {
26 + $table->boolean('restricted')->default(false);
27 + $table->index('restricted');
28 + });
29 +
30 + Schema::table('pages', function (Blueprint $table) {
31 + $table->boolean('restricted')->default(false);
32 + $table->index('restricted');
33 + });
34 +
35 + Schema::create('restrictions', function(Blueprint $table) {
36 + $table->increments('id');
37 + $table->integer('restrictable_id');
38 + $table->string('restrictable_type');
39 + $table->integer('role_id');
40 + $table->string('action');
41 + $table->index('role_id');
42 + $table->index('action');
43 + $table->index(['restrictable_id', 'restrictable_type']);
44 + });
45 + }
46 +
47 + /**
48 + * Reverse the migrations.
49 + *
50 + * @return void
51 + */
52 + public function down()
53 + {
54 + Schema::table('images', function (Blueprint $table) {
55 + $table->dropColumn('uploaded_to');
56 + });
57 +
58 + Schema::table('books', function (Blueprint $table) {
59 + $table->dropColumn('restricted');
60 + });
61 +
62 + Schema::table('chapters', function (Blueprint $table) {
63 + $table->dropColumn('restricted');
64 + });
65 +
66 +
67 + Schema::table('pages', function (Blueprint $table) {
68 + $table->dropColumn('restricted');
69 + });
70 +
71 + Schema::drop('restrictions');
72 + }
73 +}
1 +@extends('base')
2 +
3 +@section('content')
4 +
5 + <div class="container" ng-non-bindable>
6 + <h1>Book Restrictions</h1>
7 + @include('form/restriction-form', ['model' => $book])
8 + </div>
9 +
10 +@stop
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
17 <a href="{{$book->getEditUrl()}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a> 17 <a href="{{$book->getEditUrl()}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a>
18 <a href="{{ $book->getUrl() }}/sort" class="text-primary text-button"><i class="zmdi zmdi-sort"></i>Sort</a> 18 <a href="{{ $book->getUrl() }}/sort" class="text-primary text-button"><i class="zmdi zmdi-sort"></i>Sort</a>
19 @endif 19 @endif
20 + @if(userCan('restrictions-manage', $book))
21 + <a href="{{$book->getUrl()}}/restrict" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Restrict</a>
22 + @endif
20 @if(userCan('book-delete', $book)) 23 @if(userCan('book-delete', $book))
21 <a href="{{ $book->getUrl() }}/delete" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a> 24 <a href="{{ $book->getUrl() }}/delete" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a>
22 @endif 25 @endif
......
1 +@extends('base')
2 +
3 +@section('content')
4 +
5 + <div class="container" ng-non-bindable>
6 + <h1>Chapter Restrictions</h1>
7 + @include('form/restriction-form', ['model' => $chapter])
8 + </div>
9 +
10 +@stop
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
18 @if(userCan('chapter-update', $chapter)) 18 @if(userCan('chapter-update', $chapter))
19 <a href="{{$chapter->getUrl() . '/edit'}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a> 19 <a href="{{$chapter->getUrl() . '/edit'}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a>
20 @endif 20 @endif
21 + @if(userCan('restrictions-manage', $chapter))
22 + <a href="{{$chapter->getUrl()}}/restrict" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Restrict</a>
23 + @endif
21 @if(userCan('chapter-delete', $chapter)) 24 @if(userCan('chapter-delete', $chapter))
22 <a href="{{$chapter->getUrl() . '/delete'}}" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a> 25 <a href="{{$chapter->getUrl() . '/delete'}}" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a>
23 @endif 26 @endif
......
1 +
2 +<label>
3 + <input value="true" id="{{$name}}" type="checkbox" name="{{$name}}"
4 + @if($errors->has($name)) class="neg" @endif
5 + @if(old($name) || (!old() && isset($model) && $model->$name)) checked="checked" @endif
6 + >
7 + {{ $label }}
8 +</label>
9 +
10 +@if($errors->has($name))
11 + <div class="text-neg text-small">{{ $errors->first($name) }}</div>
12 +@endif
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +<label>
3 + <input value="true" id="{{$name}}[{{$role->id}}][{{$action}}]" type="checkbox" name="{{$name}}[{{$role->id}}][{{$action}}]"
4 + @if(old($name .'.'.$role->id.'.'.$action) || (!old() && isset($model) && $model->hasRestriction($role->id, $action))) checked="checked" @endif
5 + >
6 + {{ $label }}
7 +</label>
...\ No newline at end of file ...\ No newline at end of file
1 +<form action="{{ $model->getUrl() }}/restrict" method="POST">
2 + {!! csrf_field() !!}
3 + <input type="hidden" name="_method" value="PUT">
4 +
5 + <div class="form-group">
6 + @include('form/checkbox', ['name' => 'restricted', 'label' => 'Restrict this page?'])
7 + </div>
8 +
9 + <table class="table">
10 + <tr>
11 + <th>Role</th>
12 + <th @if($model->isA('page')) colspan="3" @else colspan="4" @endif>Actions</th>
13 + </tr>
14 + @foreach($roles as $role)
15 + <tr>
16 + <td>{{ $role->display_name }}</td>
17 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'View', 'action' => 'view'])</td>
18 + @if(!$model->isA('page'))
19 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Create', 'action' => 'create'])</td>
20 + @endif
21 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Update', 'action' => 'update'])</td>
22 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Delete', 'action' => 'delete'])</td>
23 + </tr>
24 + @endforeach
25 + </table>
26 +
27 + <button type="submit" class="button pos">Save Restrictions</button>
28 +</form>
...\ No newline at end of file ...\ No newline at end of file
1 +@extends('base')
2 +
3 +@section('content')
4 +
5 + <div class="container" ng-non-bindable>
6 + <h1>Page Restrictions</h1>
7 + @include('form/restriction-form', ['model' => $page])
8 + </div>
9 +
10 +@stop
...@@ -22,17 +22,20 @@ ...@@ -22,17 +22,20 @@
22 <span dropdown class="dropdown-container"> 22 <span dropdown class="dropdown-container">
23 <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>Export</div> 23 <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>Export</div>
24 <ul class="wide"> 24 <ul class="wide">
25 - <li><a href="{{$page->getUrl() . '/export/html'}}" target="_blank">Contained Web File <span class="text-muted float right">.html</span></a></li> 25 + <li><a href="{{$page->getUrl()}}/export/html" target="_blank">Contained Web File <span class="text-muted float right">.html</span></a></li>
26 - <li><a href="{{$page->getUrl() . '/export/pdf'}}" target="_blank">PDF File <span class="text-muted float right">.pdf</span></a></li> 26 + <li><a href="{{$page->getUrl()}}/export/pdf" target="_blank">PDF File <span class="text-muted float right">.pdf</span></a></li>
27 - <li><a href="{{$page->getUrl() . '/export/plaintext'}}" target="_blank">Plain Text File <span class="text-muted float right">.txt</span></a></li> 27 + <li><a href="{{$page->getUrl()}}/export/plaintext" target="_blank">Plain Text File <span class="text-muted float right">.txt</span></a></li>
28 </ul> 28 </ul>
29 </span> 29 </span>
30 @if(userCan('page-update', $page)) 30 @if(userCan('page-update', $page))
31 - <a href="{{$page->getUrl() . '/revisions'}}" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a> 31 + <a href="{{$page->getUrl()}}/revisions" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a>
32 - <a href="{{$page->getUrl() . '/edit'}}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a> 32 + <a href="{{$page->getUrl()}}/edit" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a>
33 + @endif
34 + @if(userCan('restrictions-manage', $page))
35 + <a href="{{$page->getUrl()}}/restrict" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Restrict</a>
33 @endif 36 @endif
34 @if(userCan('page-delete', $page)) 37 @if(userCan('page-delete', $page))
35 - <a href="{{$page->getUrl() . '/delete'}}" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a> 38 + <a href="{{$page->getUrl()}}/delete" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a>
36 @endif 39 @endif
37 </div> 40 </div>
38 </div> 41 </div>
......
...@@ -12,13 +12,28 @@ ...@@ -12,13 +12,28 @@
12 @include('form/text', ['name' => 'description']) 12 @include('form/text', ['name' => 'description'])
13 </div> 13 </div>
14 <hr class="even"> 14 <hr class="even">
15 + <div class="row">
16 + <div class="col-md-6">
17 + <label> @include('settings/roles/checkbox', ['permission' => 'users-manage']) Manage users</label>
18 + </div>
19 + <div class="col-md-6">
20 + <label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) Manage user roles & Permissions</label>
21 + </div>
22 + </div>
23 + <hr class="even">
24 + <div class="row">
25 + <div class="col-md-6">
26 + <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) Manage all restrictions</label>
27 + </div>
28 + <div class="col-md-6">
29 + <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-own']) Manage restrictions on own content</label>
30 + </div>
31 + </div>
32 + <hr class="even">
15 <div class="form-group"> 33 <div class="form-group">
16 - <label>Manage users @include('settings/roles/checkbox', ['permission' => 'users-manage'])</label> 34 + <label>@include('settings/roles/checkbox', ['permission' => 'settings-manage']) Manage app settings</label>
17 - <hr class="even">
18 - <label>Manage user roles & Permissions @include('settings/roles/checkbox', ['permission' => 'user-roles-manage'])</label>
19 - <hr class="even">
20 - <label>Manage app settings @include('settings/roles/checkbox', ['permission' => 'settings-manage'])</label>
21 </div> 35 </div>
36 +
22 </div> 37 </div>
23 38
24 <div class="col-md-6"> 39 <div class="col-md-6">
......