Dan Brown

Added permission system

...@@ -26,6 +26,7 @@ class BookController extends Controller ...@@ -26,6 +26,7 @@ class BookController extends Controller
26 { 26 {
27 $this->bookRepo = $bookRepo; 27 $this->bookRepo = $bookRepo;
28 $this->pageRepo = $pageRepo; 28 $this->pageRepo = $pageRepo;
29 + parent::__construct();
29 } 30 }
30 31
31 /** 32 /**
...@@ -46,19 +47,21 @@ class BookController extends Controller ...@@ -46,19 +47,21 @@ class BookController extends Controller
46 */ 47 */
47 public function create() 48 public function create()
48 { 49 {
50 + $this->checkPermission('book-create');
49 return view('books/create'); 51 return view('books/create');
50 } 52 }
51 53
52 /** 54 /**
53 * Store a newly created book in storage. 55 * Store a newly created book in storage.
54 * 56 *
55 - * @param Request $request 57 + * @param Request $request
56 * @return Response 58 * @return Response
57 */ 59 */
58 public function store(Request $request) 60 public function store(Request $request)
59 { 61 {
62 + $this->checkPermission('book-create');
60 $this->validate($request, [ 63 $this->validate($request, [
61 - 'name' => 'required|string|max:255', 64 + 'name' => 'required|string|max:255',
62 'description' => 'string|max:1000' 65 'description' => 'string|max:1000'
63 ]); 66 ]);
64 $book = $this->bookRepo->newFromInput($request->all()); 67 $book = $this->bookRepo->newFromInput($request->all());
...@@ -90,6 +93,7 @@ class BookController extends Controller ...@@ -90,6 +93,7 @@ class BookController extends Controller
90 */ 93 */
91 public function edit($slug) 94 public function edit($slug)
92 { 95 {
96 + $this->checkPermission('book-update');
93 $book = $this->bookRepo->getBySlug($slug); 97 $book = $this->bookRepo->getBySlug($slug);
94 return view('books/edit', ['book' => $book, 'current' => $book]); 98 return view('books/edit', ['book' => $book, 'current' => $book]);
95 } 99 }
...@@ -98,14 +102,15 @@ class BookController extends Controller ...@@ -98,14 +102,15 @@ class BookController extends Controller
98 * Update the specified book in storage. 102 * Update the specified book in storage.
99 * 103 *
100 * @param Request $request 104 * @param Request $request
101 - * @param $slug 105 + * @param $slug
102 * @return Response 106 * @return Response
103 */ 107 */
104 public function update(Request $request, $slug) 108 public function update(Request $request, $slug)
105 { 109 {
110 + $this->checkPermission('book-update');
106 $book = $this->bookRepo->getBySlug($slug); 111 $book = $this->bookRepo->getBySlug($slug);
107 $this->validate($request, [ 112 $this->validate($request, [
108 - 'name' => 'required|string|max:255', 113 + 'name' => 'required|string|max:255',
109 'description' => 'string|max:1000' 114 'description' => 'string|max:1000'
110 ]); 115 ]);
111 $book->fill($request->all()); 116 $book->fill($request->all());
...@@ -123,6 +128,7 @@ class BookController extends Controller ...@@ -123,6 +128,7 @@ class BookController extends Controller
123 */ 128 */
124 public function showDelete($bookSlug) 129 public function showDelete($bookSlug)
125 { 130 {
131 + $this->checkPermission('book-delete');
126 $book = $this->bookRepo->getBySlug($bookSlug); 132 $book = $this->bookRepo->getBySlug($bookSlug);
127 return view('books/delete', ['book' => $book, 'current' => $book]); 133 return view('books/delete', ['book' => $book, 'current' => $book]);
128 } 134 }
...@@ -135,6 +141,7 @@ class BookController extends Controller ...@@ -135,6 +141,7 @@ class BookController extends Controller
135 */ 141 */
136 public function destroy($bookSlug) 142 public function destroy($bookSlug)
137 { 143 {
144 + $this->checkPermission('book-delete');
138 $book = $this->bookRepo->getBySlug($bookSlug); 145 $book = $this->bookRepo->getBySlug($bookSlug);
139 Activity::addMessage('book_delete', 0, $book->name); 146 Activity::addMessage('book_delete', 0, $book->name);
140 $this->bookRepo->destroyBySlug($bookSlug); 147 $this->bookRepo->destroyBySlug($bookSlug);
......
...@@ -22,12 +22,13 @@ class ChapterController extends Controller ...@@ -22,12 +22,13 @@ class ChapterController extends Controller
22 * @param $bookRepo 22 * @param $bookRepo
23 * @param $chapterRepo 23 * @param $chapterRepo
24 */ 24 */
25 - public function __construct(BookRepo $bookRepo,ChapterRepo $chapterRepo) 25 + public function __construct(BookRepo $bookRepo, ChapterRepo $chapterRepo)
26 { 26 {
27 $this->bookRepo = $bookRepo; 27 $this->bookRepo = $bookRepo;
28 $this->chapterRepo = $chapterRepo; 28 $this->chapterRepo = $chapterRepo;
29 + parent::__construct();
29 } 30 }
30 - 31 +
31 32
32 /** 33 /**
33 * Show the form for creating a new chapter. 34 * Show the form for creating a new chapter.
...@@ -37,6 +38,7 @@ class ChapterController extends Controller ...@@ -37,6 +38,7 @@ class ChapterController extends Controller
37 */ 38 */
38 public function create($bookSlug) 39 public function create($bookSlug)
39 { 40 {
41 + $this->checkPermission('chapter-create');
40 $book = $this->bookRepo->getBySlug($bookSlug); 42 $book = $this->bookRepo->getBySlug($bookSlug);
41 return view('chapters/create', ['book' => $book, 'current' => $book]); 43 return view('chapters/create', ['book' => $book, 'current' => $book]);
42 } 44 }
...@@ -44,12 +46,13 @@ class ChapterController extends Controller ...@@ -44,12 +46,13 @@ class ChapterController extends Controller
44 /** 46 /**
45 * Store a newly created chapter in storage. 47 * Store a newly created chapter in storage.
46 * 48 *
47 - * @param $bookSlug 49 + * @param $bookSlug
48 * @param Request $request 50 * @param Request $request
49 * @return Response 51 * @return Response
50 */ 52 */
51 public function store($bookSlug, Request $request) 53 public function store($bookSlug, Request $request)
52 { 54 {
55 + $this->checkPermission('chapter-create');
53 $this->validate($request, [ 56 $this->validate($request, [
54 'name' => 'required|string|max:255' 57 'name' => 'required|string|max:255'
55 ]); 58 ]);
...@@ -88,6 +91,7 @@ class ChapterController extends Controller ...@@ -88,6 +91,7 @@ class ChapterController extends Controller
88 */ 91 */
89 public function edit($bookSlug, $chapterSlug) 92 public function edit($bookSlug, $chapterSlug)
90 { 93 {
94 + $this->checkPermission('chapter-update');
91 $book = $this->bookRepo->getBySlug($bookSlug); 95 $book = $this->bookRepo->getBySlug($bookSlug);
92 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 96 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
93 return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); 97 return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
...@@ -97,12 +101,13 @@ class ChapterController extends Controller ...@@ -97,12 +101,13 @@ class ChapterController extends Controller
97 * Update the specified chapter in storage. 101 * Update the specified chapter in storage.
98 * 102 *
99 * @param Request $request 103 * @param Request $request
100 - * @param $bookSlug 104 + * @param $bookSlug
101 - * @param $chapterSlug 105 + * @param $chapterSlug
102 * @return Response 106 * @return Response
103 */ 107 */
104 public function update(Request $request, $bookSlug, $chapterSlug) 108 public function update(Request $request, $bookSlug, $chapterSlug)
105 { 109 {
110 + $this->checkPermission('chapter-update');
106 $book = $this->bookRepo->getBySlug($bookSlug); 111 $book = $this->bookRepo->getBySlug($bookSlug);
107 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 112 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
108 $chapter->fill($request->all()); 113 $chapter->fill($request->all());
...@@ -121,6 +126,7 @@ class ChapterController extends Controller ...@@ -121,6 +126,7 @@ class ChapterController extends Controller
121 */ 126 */
122 public function showDelete($bookSlug, $chapterSlug) 127 public function showDelete($bookSlug, $chapterSlug)
123 { 128 {
129 + $this->checkPermission('chapter-delete');
124 $book = $this->bookRepo->getBySlug($bookSlug); 130 $book = $this->bookRepo->getBySlug($bookSlug);
125 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 131 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
126 return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); 132 return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
...@@ -135,10 +141,11 @@ class ChapterController extends Controller ...@@ -135,10 +141,11 @@ class ChapterController extends Controller
135 */ 141 */
136 public function destroy($bookSlug, $chapterSlug) 142 public function destroy($bookSlug, $chapterSlug)
137 { 143 {
144 + $this->checkPermission('chapter-delete');
138 $book = $this->bookRepo->getBySlug($bookSlug); 145 $book = $this->bookRepo->getBySlug($bookSlug);
139 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 146 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
140 - if(count($chapter->pages) > 0) { 147 + if (count($chapter->pages) > 0) {
141 - foreach($chapter->pages as $page) { 148 + foreach ($chapter->pages as $page) {
142 $page->chapter_id = 0; 149 $page->chapter_id = 0;
143 $page->save(); 150 $page->save();
144 } 151 }
......
...@@ -2,10 +2,13 @@ ...@@ -2,10 +2,13 @@
2 2
3 namespace Oxbow\Http\Controllers; 3 namespace Oxbow\Http\Controllers;
4 4
5 +use HttpRequestException;
5 use Illuminate\Foundation\Bus\DispatchesJobs; 6 use Illuminate\Foundation\Bus\DispatchesJobs;
7 +use Illuminate\Http\Exception\HttpResponseException;
6 use Illuminate\Routing\Controller as BaseController; 8 use Illuminate\Routing\Controller as BaseController;
7 use Illuminate\Foundation\Validation\ValidatesRequests; 9 use Illuminate\Foundation\Validation\ValidatesRequests;
8 use Illuminate\Support\Facades\Auth; 10 use Illuminate\Support\Facades\Auth;
11 +use Illuminate\Support\Facades\Session;
9 use Oxbow\User; 12 use Oxbow\User;
10 13
11 abstract class Controller extends BaseController 14 abstract class Controller extends BaseController
...@@ -13,16 +16,55 @@ abstract class Controller extends BaseController ...@@ -13,16 +16,55 @@ abstract class Controller extends BaseController
13 use DispatchesJobs, ValidatesRequests; 16 use DispatchesJobs, ValidatesRequests;
14 17
15 /** 18 /**
19 + * @var User static
20 + */
21 + protected $currentUser;
22 + /**
23 + * @var bool
24 + */
25 + protected $signedIn;
26 +
27 + /**
16 * Controller constructor. 28 * Controller constructor.
17 */ 29 */
18 public function __construct() 30 public function __construct()
19 { 31 {
20 - view()->share('signedIn', Auth::check()); 32 + // Get a user instance for the current user
21 $user = Auth::user(); 33 $user = Auth::user();
22 - if(!$user) { 34 + if (!$user) {
23 $user = User::getDefault(); 35 $user = User::getDefault();
24 } 36 }
25 - view()->share('user', $user); 37 + // Share variables with views
38 + view()->share('signedIn', Auth::check());
39 + view()->share('currentUser', $user);
40 + // Share variables with controllers
41 + $this->currentUser = $user;
42 + $this->signedIn = Auth::check();
43 + }
44 +
45 + /**
46 + * Checks for a permission.
47 + *
48 + * @param $permissionName
49 + * @return bool|\Illuminate\Http\RedirectResponse
50 + */
51 + protected function checkPermission($permissionName)
52 + {
53 + if (!$this->currentUser || !$this->currentUser->can($permissionName)) {
54 + Session::flash('error', trans('errors.permission'));
55 + throw new HttpResponseException(
56 + redirect()->back()
57 + );
58 + }
59 +
60 + return true;
61 + }
62 +
63 + protected function checkPermissionOr($permissionName, $callback)
64 + {
65 + $callbackResult = $callback();
66 + if ($callbackResult === false) $this->checkPermission($permissionName);
67 + return true;
26 } 68 }
27 69
28 } 70 }
......
...@@ -19,12 +19,13 @@ class HomeController extends Controller ...@@ -19,12 +19,13 @@ class HomeController extends Controller
19 /** 19 /**
20 * HomeController constructor. 20 * HomeController constructor.
21 * @param ActivityService $activityService 21 * @param ActivityService $activityService
22 - * @param BookRepo $bookRepo 22 + * @param BookRepo $bookRepo
23 */ 23 */
24 public function __construct(ActivityService $activityService, BookRepo $bookRepo) 24 public function __construct(ActivityService $activityService, BookRepo $bookRepo)
25 { 25 {
26 $this->activityService = $activityService; 26 $this->activityService = $activityService;
27 $this->bookRepo = $bookRepo; 27 $this->bookRepo = $bookRepo;
28 + parent::__construct();
28 } 29 }
29 30
30 31
......
...@@ -18,12 +18,13 @@ class ImageController extends Controller ...@@ -18,12 +18,13 @@ class ImageController extends Controller
18 /** 18 /**
19 * ImageController constructor. 19 * ImageController constructor.
20 * @param Image $image 20 * @param Image $image
21 - * @param File $file 21 + * @param File $file
22 */ 22 */
23 public function __construct(Image $image, File $file) 23 public function __construct(Image $image, File $file)
24 { 24 {
25 $this->image = $image; 25 $this->image = $image;
26 $this->file = $file; 26 $this->file = $file;
27 + parent::__construct();
27 } 28 }
28 29
29 /** 30 /**
...@@ -33,7 +34,7 @@ class ImageController extends Controller ...@@ -33,7 +34,7 @@ class ImageController extends Controller
33 */ 34 */
34 public function getImage(Request $request) 35 public function getImage(Request $request)
35 { 36 {
36 - $cacheTime = 60*60*24; 37 + $cacheTime = 60 * 60 * 24;
37 $path = storage_path() . '/' . $request->path(); 38 $path = storage_path() . '/' . $request->path();
38 $modifiedTime = $this->file->lastModified($path); 39 $modifiedTime = $this->file->lastModified($path);
39 $eTag = md5($modifiedTime . $path); 40 $eTag = md5($modifiedTime . $path);
...@@ -43,20 +44,20 @@ class ImageController extends Controller ...@@ -43,20 +44,20 @@ class ImageController extends Controller
43 $headers = [ 44 $headers = [
44 'Last-Modified' => $headerLastModified, 45 'Last-Modified' => $headerLastModified,
45 'Cache-Control' => 'must-revalidate', 46 'Cache-Control' => 'must-revalidate',
46 - 'Pragma' => 'public', 47 + 'Pragma' => 'public',
47 - 'Expires' => $headerExpires, 48 + 'Expires' => $headerExpires,
48 - 'Etag' => $eTag 49 + 'Etag' => $eTag
49 ]; 50 ];
50 51
51 $browserModifiedSince = $request->header('If-Modified-Since'); 52 $browserModifiedSince = $request->header('If-Modified-Since');
52 $browserNoneMatch = $request->header('If-None-Match'); 53 $browserNoneMatch = $request->header('If-None-Match');
53 - if($browserModifiedSince !== null && file_exists($path) && ($browserModifiedSince == $headerLastModified || $browserNoneMatch == $eTag)) { 54 + if ($browserModifiedSince !== null && file_exists($path) && ($browserModifiedSince == $headerLastModified || $browserNoneMatch == $eTag)) {
54 return response()->make('', 304, $headers); 55 return response()->make('', 304, $headers);
55 } 56 }
56 57
57 - if(file_exists($path)) { 58 + if (file_exists($path)) {
58 return response()->make(file_get_contents($path), 200, array_merge($headers, [ 59 return response()->make(file_get_contents($path), 200, array_merge($headers, [
59 - 'Content-Type' => $this->file->mimeType($path), 60 + 'Content-Type' => $this->file->mimeType($path),
60 'Content-Length' => filesize($path), 61 'Content-Length' => filesize($path),
61 ])); 62 ]));
62 } 63 }
...@@ -72,21 +73,21 @@ class ImageController extends Controller ...@@ -72,21 +73,21 @@ class ImageController extends Controller
72 { 73 {
73 $pageSize = 30; 74 $pageSize = 30;
74 $images = DB::table('images')->orderBy('created_at', 'desc') 75 $images = DB::table('images')->orderBy('created_at', 'desc')
75 - ->skip($page*$pageSize)->take($pageSize)->get(); 76 + ->skip($page * $pageSize)->take($pageSize)->get();
76 - foreach($images as $image) { 77 + foreach ($images as $image) {
77 $image->thumbnail = $this->getThumbnail($image, 150, 150); 78 $image->thumbnail = $this->getThumbnail($image, 150, 150);
78 } 79 }
79 $hasMore = count(DB::table('images')->orderBy('created_at', 'desc') 80 $hasMore = count(DB::table('images')->orderBy('created_at', 'desc')
80 - ->skip(($page+1)*$pageSize)->take($pageSize)->get()) > 0; 81 + ->skip(($page + 1) * $pageSize)->take($pageSize)->get()) > 0;
81 return response()->json([ 82 return response()->json([
82 - 'images' => $images, 83 + 'images' => $images,
83 'hasMore' => $hasMore 84 'hasMore' => $hasMore
84 ]); 85 ]);
85 } 86 }
86 87
87 /** 88 /**
88 * Get the thumbnail for an image. 89 * Get the thumbnail for an image.
89 - * @param $image 90 + * @param $image
90 * @param int $width 91 * @param int $width
91 * @param int $height 92 * @param int $height
92 * @return string 93 * @return string
...@@ -99,7 +100,7 @@ class ImageController extends Controller ...@@ -99,7 +100,7 @@ class ImageController extends Controller
99 $thumbFilePath = public_path() . $thumbPath; 100 $thumbFilePath = public_path() . $thumbPath;
100 101
101 // Return the thumbnail url path if already exists 102 // Return the thumbnail url path if already exists
102 - if(file_exists($thumbFilePath)) { 103 + if (file_exists($thumbFilePath)) {
103 return $thumbPath; 104 return $thumbPath;
104 } 105 }
105 106
...@@ -108,7 +109,7 @@ class ImageController extends Controller ...@@ -108,7 +109,7 @@ class ImageController extends Controller
108 $thumb->fit($width, $height); 109 $thumb->fit($width, $height);
109 110
110 // Create thumbnail folder if it does not exist 111 // Create thumbnail folder if it does not exist
111 - if(!file_exists(dirname($thumbFilePath))) { 112 + if (!file_exists(dirname($thumbFilePath))) {
112 mkdir(dirname($thumbFilePath), 0775, true); 113 mkdir(dirname($thumbFilePath), 0775, true);
113 } 114 }
114 115
...@@ -124,13 +125,14 @@ class ImageController extends Controller ...@@ -124,13 +125,14 @@ class ImageController extends Controller
124 */ 125 */
125 public function upload(Request $request) 126 public function upload(Request $request)
126 { 127 {
128 + $this->checkPermission('image-create');
127 $imageUpload = $request->file('file'); 129 $imageUpload = $request->file('file');
128 $name = str_replace(' ', '-', $imageUpload->getClientOriginalName()); 130 $name = str_replace(' ', '-', $imageUpload->getClientOriginalName());
129 $storageName = substr(sha1(time()), 0, 10) . '-' . $name; 131 $storageName = substr(sha1(time()), 0, 10) . '-' . $name;
130 - $imagePath = '/uploads/images/'.Date('Y-m-M').'/'; 132 + $imagePath = '/uploads/images/' . Date('Y-m-M') . '/';
131 - $storagePath = public_path(). $imagePath; 133 + $storagePath = public_path() . $imagePath;
132 $fullPath = $storagePath . $storageName; 134 $fullPath = $storagePath . $storageName;
133 - while(file_exists($fullPath)) { 135 + while (file_exists($fullPath)) {
134 $storageName = substr(sha1(rand()), 0, 3) . $storageName; 136 $storageName = substr(sha1(rand()), 0, 3) . $storageName;
135 $fullPath = $storagePath . $storageName; 137 $fullPath = $storagePath . $storageName;
136 } 138 }
...@@ -147,12 +149,13 @@ class ImageController extends Controller ...@@ -147,12 +149,13 @@ class ImageController extends Controller
147 149
148 /** 150 /**
149 * Update image details 151 * Update image details
150 - * @param $imageId 152 + * @param $imageId
151 * @param Request $request 153 * @param Request $request
152 * @return \Illuminate\Http\JsonResponse 154 * @return \Illuminate\Http\JsonResponse
153 */ 155 */
154 public function update($imageId, Request $request) 156 public function update($imageId, Request $request)
155 { 157 {
158 + $this->checkPermission('image-update');
156 $this->validate($request, [ 159 $this->validate($request, [
157 'name' => 'required|min:2|string' 160 'name' => 'required|min:2|string'
158 ]); 161 ]);
...@@ -169,6 +172,7 @@ class ImageController extends Controller ...@@ -169,6 +172,7 @@ class ImageController extends Controller
169 */ 172 */
170 public function destroy($id) 173 public function destroy($id)
171 { 174 {
175 + $this->checkPermission('image-delete');
172 $image = $this->image->findOrFail($id); 176 $image = $this->image->findOrFail($id);
173 177
174 // Delete files 178 // Delete files
...@@ -176,14 +180,14 @@ class ImageController extends Controller ...@@ -176,14 +180,14 @@ class ImageController extends Controller
176 $fileName = basename($image->url); 180 $fileName = basename($image->url);
177 181
178 // Delete thumbnails 182 // Delete thumbnails
179 - foreach(glob($folder . '/*') as $file) { 183 + foreach (glob($folder . '/*') as $file) {
180 - if(is_dir($file)) { 184 + if (is_dir($file)) {
181 $thumbName = $file . '/' . $fileName; 185 $thumbName = $file . '/' . $fileName;
182 - if(file_exists($file)) { 186 + if (file_exists($file)) {
183 unlink($thumbName); 187 unlink($thumbName);
184 } 188 }
185 // Remove thumb folder if empty 189 // Remove thumb folder if empty
186 - if(count(glob($file . '/*')) === 0) { 190 + if (count(glob($file . '/*')) === 0) {
187 rmdir($file); 191 rmdir($file);
188 } 192 }
189 } 193 }
...@@ -194,7 +198,7 @@ class ImageController extends Controller ...@@ -194,7 +198,7 @@ class ImageController extends Controller
194 $image->delete(); 198 $image->delete();
195 199
196 // Delete parent folder if empty 200 // Delete parent folder if empty
197 - if(count(glob($folder . '/*')) === 0) { 201 + if (count(glob($folder . '/*')) === 0) {
198 rmdir($folder); 202 rmdir($folder);
199 } 203 }
200 return response()->json('Image Deleted'); 204 return response()->json('Image Deleted');
......
...@@ -20,8 +20,8 @@ class PageController extends Controller ...@@ -20,8 +20,8 @@ class PageController extends Controller
20 20
21 /** 21 /**
22 * PageController constructor. 22 * PageController constructor.
23 - * @param PageRepo $pageRepo 23 + * @param PageRepo $pageRepo
24 - * @param BookRepo $bookRepo 24 + * @param BookRepo $bookRepo
25 * @param ChapterRepo $chapterRepo 25 * @param ChapterRepo $chapterRepo
26 */ 26 */
27 public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo) 27 public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo)
...@@ -29,18 +29,20 @@ class PageController extends Controller ...@@ -29,18 +29,20 @@ class PageController extends Controller
29 $this->pageRepo = $pageRepo; 29 $this->pageRepo = $pageRepo;
30 $this->bookRepo = $bookRepo; 30 $this->bookRepo = $bookRepo;
31 $this->chapterRepo = $chapterRepo; 31 $this->chapterRepo = $chapterRepo;
32 + parent::__construct();
32 } 33 }
33 34
34 /** 35 /**
35 * Show the form for creating a new page. 36 * Show the form for creating a new page.
36 * 37 *
37 - * @param $bookSlug 38 + * @param $bookSlug
38 * @param bool $chapterSlug 39 * @param bool $chapterSlug
39 * @return Response 40 * @return Response
40 * @internal param bool $pageSlug 41 * @internal param bool $pageSlug
41 */ 42 */
42 public function create($bookSlug, $chapterSlug = false) 43 public function create($bookSlug, $chapterSlug = false)
43 { 44 {
45 + $this->checkPermission('page-create');
44 $book = $this->bookRepo->getBySlug($bookSlug); 46 $book = $this->bookRepo->getBySlug($bookSlug);
45 $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false; 47 $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false;
46 return view('pages/create', ['book' => $book, 'chapter' => $chapter]); 48 return view('pages/create', ['book' => $book, 'chapter' => $chapter]);
...@@ -50,14 +52,15 @@ class PageController extends Controller ...@@ -50,14 +52,15 @@ class PageController extends Controller
50 * Store a newly created page in storage. 52 * Store a newly created page in storage.
51 * 53 *
52 * @param Request $request 54 * @param Request $request
53 - * @param $bookSlug 55 + * @param $bookSlug
54 * @return Response 56 * @return Response
55 */ 57 */
56 public function store(Request $request, $bookSlug) 58 public function store(Request $request, $bookSlug)
57 { 59 {
60 + $this->checkPermission('page-create');
58 $this->validate($request, [ 61 $this->validate($request, [
59 - 'name' => 'required|string|max:255', 62 + 'name' => 'required|string|max:255',
60 - 'html' => 'required|string', 63 + 'html' => 'required|string',
61 'parent' => 'integer|exists:pages,id' 64 'parent' => 'integer|exists:pages,id'
62 ]); 65 ]);
63 $book = $this->bookRepo->getBySlug($bookSlug); 66 $book = $this->bookRepo->getBySlug($bookSlug);
...@@ -66,7 +69,7 @@ class PageController extends Controller ...@@ -66,7 +69,7 @@ class PageController extends Controller
66 $page->slug = $this->pageRepo->findSuitableSlug($page->name, $book->id); 69 $page->slug = $this->pageRepo->findSuitableSlug($page->name, $book->id);
67 $page->priority = $this->bookRepo->getNewPriority($book); 70 $page->priority = $this->bookRepo->getNewPriority($book);
68 71
69 - if($request->has('chapter') && $this->chapterRepo->idExists($request->get('chapter'))) { 72 + if ($request->has('chapter') && $this->chapterRepo->idExists($request->get('chapter'))) {
70 $page->chapter_id = $request->get('chapter'); 73 $page->chapter_id = $request->get('chapter');
71 } 74 }
72 75
...@@ -103,6 +106,7 @@ class PageController extends Controller ...@@ -103,6 +106,7 @@ class PageController extends Controller
103 */ 106 */
104 public function edit($bookSlug, $pageSlug) 107 public function edit($bookSlug, $pageSlug)
105 { 108 {
109 + $this->checkPermission('page-update');
106 $book = $this->bookRepo->getBySlug($bookSlug); 110 $book = $this->bookRepo->getBySlug($bookSlug);
107 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 111 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
108 return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]); 112 return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]);
...@@ -112,12 +116,13 @@ class PageController extends Controller ...@@ -112,12 +116,13 @@ class PageController extends Controller
112 * Update the specified page in storage. 116 * Update the specified page in storage.
113 * 117 *
114 * @param Request $request 118 * @param Request $request
115 - * @param $bookSlug 119 + * @param $bookSlug
116 - * @param $pageSlug 120 + * @param $pageSlug
117 * @return Response 121 * @return Response
118 */ 122 */
119 public function update(Request $request, $bookSlug, $pageSlug) 123 public function update(Request $request, $bookSlug, $pageSlug)
120 { 124 {
125 + $this->checkPermission('page-update');
121 $book = $this->bookRepo->getBySlug($bookSlug); 126 $book = $this->bookRepo->getBySlug($bookSlug);
122 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 127 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
123 $this->pageRepo->updatePage($page, $book->id, $request->all()); 128 $this->pageRepo->updatePage($page, $book->id, $request->all());
...@@ -145,7 +150,7 @@ class PageController extends Controller ...@@ -145,7 +150,7 @@ class PageController extends Controller
145 public function searchAll(Request $request) 150 public function searchAll(Request $request)
146 { 151 {
147 $searchTerm = $request->get('term'); 152 $searchTerm = $request->get('term');
148 - if(empty($searchTerm)) return redirect()->back(); 153 + if (empty($searchTerm)) return redirect()->back();
149 154
150 $pages = $this->pageRepo->getBySearch($searchTerm); 155 $pages = $this->pageRepo->getBySearch($searchTerm);
151 return view('pages/search-results', ['pages' => $pages, 'searchTerm' => $searchTerm]); 156 return view('pages/search-results', ['pages' => $pages, 'searchTerm' => $searchTerm]);
...@@ -158,6 +163,7 @@ class PageController extends Controller ...@@ -158,6 +163,7 @@ class PageController extends Controller
158 */ 163 */
159 public function sortPages($bookSlug) 164 public function sortPages($bookSlug)
160 { 165 {
166 + $this->checkPermission('book-update');
161 $book = $this->bookRepo->getBySlug($bookSlug); 167 $book = $this->bookRepo->getBySlug($bookSlug);
162 return view('pages/sort', ['book' => $book, 'current' => $book]); 168 return view('pages/sort', ['book' => $book, 'current' => $book]);
163 } 169 }
...@@ -165,26 +171,27 @@ class PageController extends Controller ...@@ -165,26 +171,27 @@ class PageController extends Controller
165 /** 171 /**
166 * Saves an array of sort mapping to pages and chapters. 172 * Saves an array of sort mapping to pages and chapters.
167 * 173 *
168 - * @param $bookSlug 174 + * @param $bookSlug
169 * @param Request $request 175 * @param Request $request
170 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector 176 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
171 */ 177 */
172 public function savePageSort($bookSlug, Request $request) 178 public function savePageSort($bookSlug, Request $request)
173 { 179 {
180 + $this->checkPermission('book-update');
174 $book = $this->bookRepo->getBySlug($bookSlug); 181 $book = $this->bookRepo->getBySlug($bookSlug);
175 // Return if no map sent 182 // Return if no map sent
176 - if(!$request->has('sort-tree')) { 183 + if (!$request->has('sort-tree')) {
177 return redirect($book->getUrl()); 184 return redirect($book->getUrl());
178 } 185 }
179 186
180 // Sort pages and chapters 187 // Sort pages and chapters
181 $sortMap = json_decode($request->get('sort-tree')); 188 $sortMap = json_decode($request->get('sort-tree'));
182 - foreach($sortMap as $index => $bookChild) { 189 + foreach ($sortMap as $index => $bookChild) {
183 $id = $bookChild->id; 190 $id = $bookChild->id;
184 $isPage = $bookChild->type == 'page'; 191 $isPage = $bookChild->type == 'page';
185 $model = $isPage ? $this->pageRepo->getById($id) : $this->chapterRepo->getById($id); 192 $model = $isPage ? $this->pageRepo->getById($id) : $this->chapterRepo->getById($id);
186 $model->priority = $index; 193 $model->priority = $index;
187 - if($isPage) { 194 + if ($isPage) {
188 $model->chapter_id = ($bookChild->parentChapter === false) ? 0 : $bookChild->parentChapter; 195 $model->chapter_id = ($bookChild->parentChapter === false) ? 0 : $bookChild->parentChapter;
189 } 196 }
190 $model->save(); 197 $model->save();
...@@ -201,6 +208,7 @@ class PageController extends Controller ...@@ -201,6 +208,7 @@ class PageController extends Controller
201 */ 208 */
202 public function showDelete($bookSlug, $pageSlug) 209 public function showDelete($bookSlug, $pageSlug)
203 { 210 {
211 + $this->checkPermission('page-delete');
204 $book = $this->bookRepo->getBySlug($bookSlug); 212 $book = $this->bookRepo->getBySlug($bookSlug);
205 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 213 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
206 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]); 214 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]);
...@@ -216,6 +224,7 @@ class PageController extends Controller ...@@ -216,6 +224,7 @@ class PageController extends Controller
216 */ 224 */
217 public function destroy($bookSlug, $pageSlug) 225 public function destroy($bookSlug, $pageSlug)
218 { 226 {
227 + $this->checkPermission('page-delete');
219 $book = $this->bookRepo->getBySlug($bookSlug); 228 $book = $this->bookRepo->getBySlug($bookSlug);
220 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 229 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
221 Activity::addMessage('page_delete', $book->id, $page->name); 230 Activity::addMessage('page_delete', $book->id, $page->name);
...@@ -255,6 +264,7 @@ class PageController extends Controller ...@@ -255,6 +264,7 @@ class PageController extends Controller
255 264
256 public function restoreRevision($bookSlug, $pageSlug, $revisionId) 265 public function restoreRevision($bookSlug, $pageSlug, $revisionId)
257 { 266 {
267 + $this->checkPermission('page-update');
258 $book = $this->bookRepo->getBySlug($bookSlug); 268 $book = $this->bookRepo->getBySlug($bookSlug);
259 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 269 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
260 $revision = $this->pageRepo->getRevisionById($revisionId); 270 $revision = $this->pageRepo->getRevisionById($revisionId);
......
...@@ -6,7 +6,6 @@ use Illuminate\Http\Request; ...@@ -6,7 +6,6 @@ use Illuminate\Http\Request;
6 6
7 use Illuminate\Support\Facades\Hash; 7 use Illuminate\Support\Facades\Hash;
8 use Oxbow\Http\Requests; 8 use Oxbow\Http\Requests;
9 -use Oxbow\Http\Controllers\Controller;
10 use Oxbow\User; 9 use Oxbow\User;
11 10
12 class UserController extends Controller 11 class UserController extends Controller
...@@ -21,9 +20,9 @@ class UserController extends Controller ...@@ -21,9 +20,9 @@ class UserController extends Controller
21 public function __construct(User $user) 20 public function __construct(User $user)
22 { 21 {
23 $this->user = $user; 22 $this->user = $user;
23 + parent::__construct();
24 } 24 }
25 25
26 -
27 /** 26 /**
28 * Display a listing of the users. 27 * Display a listing of the users.
29 * 28 *
...@@ -32,7 +31,7 @@ class UserController extends Controller ...@@ -32,7 +31,7 @@ class UserController extends Controller
32 public function index() 31 public function index()
33 { 32 {
34 $users = $this->user->all(); 33 $users = $this->user->all();
35 - return view('users/index', ['users'=> $users]); 34 + return view('users/index', ['users' => $users]);
36 } 35 }
37 36
38 /** 37 /**
...@@ -42,27 +41,32 @@ class UserController extends Controller ...@@ -42,27 +41,32 @@ class UserController extends Controller
42 */ 41 */
43 public function create() 42 public function create()
44 { 43 {
44 + $this->checkPermission('user-create');
45 return view('users/create'); 45 return view('users/create');
46 } 46 }
47 47
48 /** 48 /**
49 * Store a newly created user in storage. 49 * Store a newly created user in storage.
50 * 50 *
51 - * @param Request $request 51 + * @param Request $request
52 * @return Response 52 * @return Response
53 */ 53 */
54 public function store(Request $request) 54 public function store(Request $request)
55 { 55 {
56 + $this->checkPermission('user-create');
56 $this->validate($request, [ 57 $this->validate($request, [
57 - 'name' => 'required', 58 + 'name' => 'required',
58 - 'email' => 'required|email', 59 + 'email' => 'required|email',
59 - 'password' => 'required|min:5', 60 + 'password' => 'required|min:5',
60 - 'password-confirm' => 'required|same:password' 61 + 'password-confirm' => 'required|same:password',
62 + 'role' => 'required|exists:roles,id'
61 ]); 63 ]);
62 64
63 $user = $this->user->fill($request->all()); 65 $user = $this->user->fill($request->all());
64 $user->password = Hash::make($request->get('password')); 66 $user->password = Hash::make($request->get('password'));
65 $user->save(); 67 $user->save();
68 +
69 + $user->attachRoleId($request->get('role'));
66 return redirect('/users'); 70 return redirect('/users');
67 } 71 }
68 72
...@@ -70,11 +74,14 @@ class UserController extends Controller ...@@ -70,11 +74,14 @@ class UserController extends Controller
70 /** 74 /**
71 * Show the form for editing the specified user. 75 * Show the form for editing the specified user.
72 * 76 *
73 - * @param int $id 77 + * @param int $id
74 * @return Response 78 * @return Response
75 */ 79 */
76 public function edit($id) 80 public function edit($id)
77 { 81 {
82 + $this->checkPermissionOr('user-update', function () use ($id) {
83 + return $this->currentUser->id == $id;
84 + });
78 $user = $this->user->findOrFail($id); 85 $user = $this->user->findOrFail($id);
79 return view('users/edit', ['user' => $user]); 86 return view('users/edit', ['user' => $user]);
80 } 87 }
...@@ -82,23 +89,31 @@ class UserController extends Controller ...@@ -82,23 +89,31 @@ class UserController extends Controller
82 /** 89 /**
83 * Update the specified user in storage. 90 * Update the specified user in storage.
84 * 91 *
85 - * @param Request $request 92 + * @param Request $request
86 - * @param int $id 93 + * @param int $id
87 * @return Response 94 * @return Response
88 */ 95 */
89 public function update(Request $request, $id) 96 public function update(Request $request, $id)
90 { 97 {
98 + $this->checkPermissionOr('user-update', function () use ($id) {
99 + return $this->currentUser->id == $id;
100 + });
91 $this->validate($request, [ 101 $this->validate($request, [
92 - 'name' => 'required', 102 + 'name' => 'required',
93 - 'email' => 'required|email', 103 + 'email' => 'required|email',
94 - 'password' => 'min:5', 104 + 'password' => 'min:5',
95 - 'password-confirm' => 'same:password' 105 + 'password-confirm' => 'same:password',
106 + 'role' => 'exists:roles,id'
96 ]); 107 ]);
97 108
98 $user = $this->user->findOrFail($id); 109 $user = $this->user->findOrFail($id);
99 $user->fill($request->all()); 110 $user->fill($request->all());
100 111
101 - if($request->has('password') && $request->get('password') != '') { 112 + if ($this->currentUser->can('user-update') && $request->has('role')) {
113 + $user->attachRoleId($request->get('role'));
114 + }
115 +
116 + if ($request->has('password') && $request->get('password') != '') {
102 $password = $request->get('password'); 117 $password = $request->get('password');
103 $user->password = Hash::make($password); 118 $user->password = Hash::make($password);
104 } 119 }
...@@ -113,6 +128,9 @@ class UserController extends Controller ...@@ -113,6 +128,9 @@ class UserController extends Controller
113 */ 128 */
114 public function delete($id) 129 public function delete($id)
115 { 130 {
131 + $this->checkPermissionOr('user-delete', function () use ($id) {
132 + return $this->currentUser->id == $id;
133 + });
116 $user = $this->user->findOrFail($id); 134 $user = $this->user->findOrFail($id);
117 return view('users/delete', ['user' => $user]); 135 return view('users/delete', ['user' => $user]);
118 } 136 }
...@@ -120,11 +138,14 @@ class UserController extends Controller ...@@ -120,11 +138,14 @@ class UserController extends Controller
120 /** 138 /**
121 * Remove the specified user from storage. 139 * Remove the specified user from storage.
122 * 140 *
123 - * @param int $id 141 + * @param int $id
124 * @return Response 142 * @return Response
125 */ 143 */
126 public function destroy($id) 144 public function destroy($id)
127 { 145 {
146 + $this->checkPermissionOr('user-delete', function () use ($id) {
147 + return $this->currentUser->id == $id;
148 + });
128 $user = $this->user->findOrFail($id); 149 $user = $this->user->findOrFail($id);
129 $user->delete(); 150 $user->delete();
130 return redirect('/users'); 151 return redirect('/users');
......
...@@ -26,8 +26,9 @@ class Kernel extends HttpKernel ...@@ -26,8 +26,9 @@ class Kernel extends HttpKernel
26 * @var array 26 * @var array
27 */ 27 */
28 protected $routeMiddleware = [ 28 protected $routeMiddleware = [
29 - 'auth' => \Oxbow\Http\Middleware\Authenticate::class, 29 + 'auth' => \Oxbow\Http\Middleware\Authenticate::class,
30 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 30 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
31 - 'guest' => \Oxbow\Http\Middleware\RedirectIfAuthenticated::class, 31 + 'guest' => \Oxbow\Http\Middleware\RedirectIfAuthenticated::class,
32 + 'perm' => \Oxbow\Http\Middleware\PermissionMiddleware::class
32 ]; 33 ];
33 } 34 }
......
1 +<?php
2 +
3 +namespace Oxbow\Http\Middleware;
4 +
5 +use Closure;
6 +use Illuminate\Support\Facades\Session;
7 +
8 +class PermissionMiddleware
9 +{
10 + /**
11 + * Handle an incoming request.
12 + *
13 + * @param \Illuminate\Http\Request $request
14 + * @param \Closure $next
15 + * @param $permission
16 + * @return mixed
17 + */
18 + public function handle($request, Closure $next, $permission)
19 + {
20 +
21 + if (!$request->user() || !$request->user()->can($permission)) {
22 + Session::flash('error', trans('errors.permission'));
23 + return redirect()->back();
24 + }
25 +
26 + return $next($request);
27 + }
28 +}
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
11 | 11 |
12 */ 12 */
13 13
14 - 14 +Route::get('/test', function () {
15 + return Auth::user()->can('users-edit');
16 +});
15 17
16 // Authentication routes... 18 // Authentication routes...
17 -Route::group(['middleware' => 'auth'], function() { 19 +Route::group(['middleware' => 'auth'], function () {
18 20
19 - Route::group(['prefix' => 'books'], function() { 21 + Route::group(['prefix' => 'books'], function () {
20 22
21 // Books 23 // Books
22 Route::get('/', 'BookController@index'); 24 Route::get('/', 'BookController@index');
......
1 +<?php
2 +
3 +namespace Oxbow;
4 +
5 +use Illuminate\Database\Eloquent\Model;
6 +
7 +class Permission extends Model
8 +{
9 + /**
10 + * The roles that belong to the permission.
11 + */
12 + public function roles()
13 + {
14 + return $this->belongsToMany('Oxbow\Permissions');
15 + }
16 +}
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
2 2
3 namespace Oxbow\Providers; 3 namespace Oxbow\Providers;
4 4
5 +use Illuminate\Support\Facades\Auth;
5 use Illuminate\Support\ServiceProvider; 6 use Illuminate\Support\ServiceProvider;
7 +use Oxbow\User;
6 8
7 class AppServiceProvider extends ServiceProvider 9 class AppServiceProvider extends ServiceProvider
8 { 10 {
......
1 +<?php
2 +
3 +namespace Oxbow;
4 +
5 +use Illuminate\Database\Eloquent\Model;
6 +
7 +class Role extends Model
8 +{
9 + /**
10 + * The roles that belong to the role.
11 + */
12 + public function users()
13 + {
14 + return $this->belongsToMany('Oxbow\User');
15 + }
16 +
17 + /**
18 + * The permissions that belong to the role.
19 + */
20 + public function permissions()
21 + {
22 + return $this->belongsToMany('Oxbow\Permission');
23 + }
24 +
25 + /**
26 + * Add a permission to this role.
27 + * @param Permission $permission
28 + */
29 + public function attachPermission(Permission $permission)
30 + {
31 + $this->permissions()->attach($permission->id);
32 + }
33 +
34 +}
...@@ -40,13 +40,63 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon ...@@ -40,13 +40,63 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
40 { 40 {
41 return new static([ 41 return new static([
42 'email' => 'guest', 42 'email' => 'guest',
43 - 'name' => 'Guest' 43 + 'name' => 'Guest'
44 ]); 44 ]);
45 } 45 }
46 46
47 /** 47 /**
48 + * Permissions and roles
49 + */
50 +
51 + /**
52 + * The roles that belong to the user.
53 + */
54 + public function roles()
55 + {
56 + return $this->belongsToMany('Oxbow\Role');
57 + }
58 +
59 + public function getRoleAttribute()
60 + {
61 + return $this->roles()->first();
62 + }
63 +
64 + /**
65 + * Check if the user has a particular permission.
66 + * @param $permissionName
67 + * @return bool
68 + */
69 + public function can($permissionName)
70 + {
71 + $permissions = $this->role->permissions()->get();
72 + $permissionSearch = $permissions->search(function ($item, $key) use ($permissionName) {
73 + return $item->name == $permissionName;
74 + });
75 + return $permissionSearch !== false;
76 + }
77 +
78 + /**
79 + * Attach a role to this user.
80 + * @param Role $role
81 + */
82 + public function attachRole(Role $role)
83 + {
84 + $this->attachRoleId($role->id);
85 + }
86 +
87 + /**
88 + * Attach a role id to this user.
89 + * @param $id
90 + */
91 + public function attachRoleId($id)
92 + {
93 + $this->roles()->sync([$id]);
94 + }
95 +
96 + /**
48 * Returns the user's avatar, 97 * Returns the user's avatar,
49 * Uses Gravatar as the avatar service. 98 * Uses Gravatar as the avatar service.
99 + *
50 * @param int $size 100 * @param int $size
51 * @return string 101 * @return string
52 */ 102 */
......
...@@ -20,6 +20,12 @@ class CreateUsersTable extends Migration ...@@ -20,6 +20,12 @@ class CreateUsersTable extends Migration
20 $table->rememberToken(); 20 $table->rememberToken();
21 $table->timestamps(); 21 $table->timestamps();
22 }); 22 });
23 +
24 + \Oxbow\User::create([
25 + 'name' => 'Admin',
26 + 'email' => 'admin@admin.com',
27 + 'password' => \Illuminate\Support\Facades\Hash::make('password')
28 + ]);
23 } 29 }
24 30
25 /** 31 /**
......
1 +<?php
2 +
3 +use Illuminate\Database\Schema\Blueprint;
4 +use Illuminate\Database\Migrations\Migration;
5 +
6 +/**
7 + * Much of this code has been taken from entrust,
8 + * a role & permission management solution for Laravel.
9 + *
10 + * Full attribution of the database Schema shown below goes to the entrust project.
11 + *
12 + * @license MIT
13 + * @package Zizaco\Entrust
14 + * @url https://github.com/Zizaco/entrust
15 + */
16 +class AddRolesAndPermissions extends Migration
17 +{
18 + /**
19 + * Run the migrations.
20 + *
21 + * @return void
22 + */
23 + public function up()
24 + {
25 + // Create table for storing roles
26 + Schema::create('roles', function (Blueprint $table) {
27 + $table->increments('id');
28 + $table->string('name')->unique();
29 + $table->string('display_name')->nullable();
30 + $table->string('description')->nullable();
31 + $table->timestamps();
32 + });
33 +
34 + // Create table for associating roles to users (Many-to-Many)
35 + Schema::create('role_user', function (Blueprint $table) {
36 + $table->integer('user_id')->unsigned();
37 + $table->integer('role_id')->unsigned();
38 +
39 + $table->foreign('user_id')->references('id')->on('users')
40 + ->onUpdate('cascade')->onDelete('cascade');
41 + $table->foreign('role_id')->references('id')->on('roles')
42 + ->onUpdate('cascade')->onDelete('cascade');
43 +
44 + $table->primary(['user_id', 'role_id']);
45 + });
46 +
47 + // Create table for storing permissions
48 + Schema::create('permissions', function (Blueprint $table) {
49 + $table->increments('id');
50 + $table->string('name')->unique();
51 + $table->string('display_name')->nullable();
52 + $table->string('description')->nullable();
53 + $table->timestamps();
54 + });
55 +
56 + // Create table for associating permissions to roles (Many-to-Many)
57 + Schema::create('permission_role', function (Blueprint $table) {
58 + $table->integer('permission_id')->unsigned();
59 + $table->integer('role_id')->unsigned();
60 +
61 + $table->foreign('permission_id')->references('id')->on('permissions')
62 + ->onUpdate('cascade')->onDelete('cascade');
63 + $table->foreign('role_id')->references('id')->on('roles')
64 + ->onUpdate('cascade')->onDelete('cascade');
65 +
66 + $table->primary(['permission_id', 'role_id']);
67 + });
68 +
69 +
70 + // Create default roles
71 + $admin = new \Oxbow\Role();
72 + $admin->name = 'admin';
73 + $admin->display_name = 'Admin';
74 + $admin->description = 'Administrator of the whole application';
75 + $admin->save();
76 +
77 + $editor = new \Oxbow\Role();
78 + $editor->name = 'editor';
79 + $editor->display_name = 'Editor';
80 + $editor->description = 'User can edit Books, Chapters & Pages';
81 + $editor->save();
82 +
83 + $viewer = new \Oxbow\Role();
84 + $viewer->name = 'viewer';
85 + $viewer->display_name = 'Viewer';
86 + $viewer->description = 'User can view books & their content behind authentication';
87 + $viewer->save();
88 +
89 + // Create default CRUD permissions and allocate to admins and editors
90 + $entities = ['Book', 'Page', 'Chapter', 'Image'];
91 + $ops = ['Create', 'Update', 'Delete'];
92 + foreach ($entities as $entity) {
93 + foreach ($ops as $op) {
94 + $newPermission = new \Oxbow\Permission();
95 + $newPermission->name = strtolower($entity) . '-' . strtolower($op);
96 + $newPermission->display_name = $op . ' ' . $entity . 's';
97 + $newPermission->save();
98 + $admin->attachPermission($newPermission);
99 + $editor->attachPermission($newPermission);
100 + }
101 + }
102 +
103 + // Create admin permissions
104 + $entities = ['Settings', 'User'];
105 + $ops = ['Create', 'Update', 'Delete'];
106 + foreach ($entities as $entity) {
107 + foreach ($ops as $op) {
108 + $newPermission = new \Oxbow\Permission();
109 + $newPermission->name = strtolower($entity) . '-' . strtolower($op);
110 + $newPermission->display_name = $op . ' ' . $entity;
111 + $newPermission->save();
112 + $admin->attachPermission($newPermission);
113 + }
114 + }
115 +
116 + // Set all current users as admins
117 + // (At this point only the initially create user should be an admin)
118 + $users = \Oxbow\User::all();
119 + foreach ($users as $user) {
120 + $user->attachRole($admin);
121 + }
122 +
123 + }
124 +
125 + /**
126 + * Reverse the migrations.
127 + *
128 + * @return void
129 + */
130 + public function down()
131 + {
132 + Schema::drop('permission_role');
133 + Schema::drop('permissions');
134 + Schema::drop('role_user');
135 + Schema::drop('roles');
136 + }
137 +}
...@@ -15,11 +15,6 @@ class DatabaseSeeder extends Seeder ...@@ -15,11 +15,6 @@ class DatabaseSeeder extends Seeder
15 Model::unguard(); 15 Model::unguard();
16 16
17 // $this->call(UserTableSeeder::class); 17 // $this->call(UserTableSeeder::class);
18 - \Oxbow\User::create([
19 - 'name' => 'Admin',
20 - 'email' => 'admin@admin.com',
21 - 'password' => \Illuminate\Support\Facades\Hash::make('password')
22 - ]);
23 18
24 Model::reguard(); 19 Model::reguard();
25 } 20 }
......
...@@ -60,6 +60,11 @@ ...@@ -60,6 +60,11 @@
60 &.large { 60 &.large {
61 padding: $-xl; 61 padding: $-xl;
62 } 62 }
63 + >h1, >h2, >h3, >h4 {
64 + &:first-child {
65 + margin-top: 0.1em;
66 + }
67 + }
63 } 68 }
64 .padded-vertical, .padded-top { 69 .padded-vertical, .padded-top {
65 padding-top: $-m; 70 padding-top: $-m;
...@@ -67,6 +72,7 @@ ...@@ -67,6 +72,7 @@
67 padding-top: $-xl; 72 padding-top: $-xl;
68 } 73 }
69 } 74 }
75 +
70 .padded-vertical, .padded-bottom { 76 .padded-vertical, .padded-bottom {
71 padding-bottom: $-m; 77 padding-bottom: $-m;
72 &.large { 78 &.large {
......
...@@ -197,7 +197,7 @@ p.secondary, p .secondary, span.secondary, .text-secondary { ...@@ -197,7 +197,7 @@ p.secondary, p .secondary, span.secondary, .text-secondary {
197 */ 197 */
198 ul { 198 ul {
199 list-style: disc; 199 list-style: disc;
200 - margin-left: $-m; 200 + margin-left: $-m*1.5;
201 } 201 }
202 202
203 /* 203 /*
......
1 +<?php
2 +
3 +return [
4 +
5 + /**
6 + * Error text strings.
7 + */
8 +
9 + // Pages
10 + 'permission' => 'You do not have permission to access the requested page.',
11 +];
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +<select id="{{ $name }}" name="{{ $name }}">
3 + @foreach($options as $option)
4 + <option value="{{$option->id}}"
5 + @if($errors->has($name)) class="neg" @endif
6 + @if(isset($model) || old($name)) @if(old($name) && old($name) === $option->id) selected @elseif(isset($model) && $model->id === $option->id) selected @endif @endif
7 + >
8 + {{ $option->$displayKey }}
9 + </option>
10 + @endforeach
11 +</select>
12 +
13 +@if($errors->has($name))
14 + <div class="text-neg text-small">{{ $errors->first($name) }}</div>
15 +@endif
...\ No newline at end of file ...\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
14 14
15 <div class="row"> 15 <div class="row">
16 <div class="page-content"> 16 <div class="page-content">
17 +
17 <div class="row"> 18 <div class="row">
18 <div class="col-md-6"> 19 <div class="col-md-6">
19 <h1>Edit User</h1> 20 <h1>Edit User</h1>
...@@ -33,6 +34,24 @@ ...@@ -33,6 +34,24 @@
33 </div> 34 </div>
34 </div> 35 </div>
35 </div> 36 </div>
37 +
38 + <hr class="margin-top large">
39 +
40 + <div class="row">
41 + <div class="col-md-12">
42 + <h3>Permissions</h3>
43 + <p>User Role: <strong>{{$user->role->display_name}}</strong>.</p>
44 + <ul class="text-muted">
45 + @foreach($user->role->permissions as $permission)
46 + <li>
47 + {{ $permission->display_name }}
48 + </li>
49 + @endforeach
50 + </ul>
51 +
52 + </div>
53 + </div>
54 +
36 </div> 55 </div>
37 </div> 56 </div>
38 57
......
1 -
2 <div class="form-group"> 1 <div class="form-group">
3 <label for="name">Name</label> 2 <label for="name">Name</label>
4 @include('form/text', ['name' => 'name']) 3 @include('form/text', ['name' => 'name'])
...@@ -10,11 +9,18 @@ ...@@ -10,11 +9,18 @@
10 </div> 9 </div>
11 10
12 @if(isset($model)) 11 @if(isset($model))
13 -<div class="form-group"> 12 + <div class="form-group">
14 <span class="text-muted"> 13 <span class="text-muted">
15 Only fill the below if you would like <br>to change your password: 14 Only fill the below if you would like <br>to change your password:
16 </span> 15 </span>
17 -</div> 16 + </div>
17 +@endif
18 +
19 +@if($currentUser->can('user-update'))
20 + <div class="form-group">
21 + <label for="role">User Role</label>
22 + @include('form/model-select', ['name' => 'role', 'options' => \Oxbow\Role::all(), 'displayKey' => 'display_name'])
23 + </div>
18 @endif 24 @endif
19 25
20 <div class="form-group"> 26 <div class="form-group">
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
8 <div class="col-md-6"></div> 8 <div class="col-md-6"></div>
9 <div class="col-md-6 faded"> 9 <div class="col-md-6 faded">
10 <div class="action-buttons"> 10 <div class="action-buttons">
11 - <a href="/users/create" class="text-pos"><i class="zmdi zmdi-account-add"></i>New User</a> 11 + @if($currentUser->can('user-create'))
12 + <a href="/users/create" class="text-pos"><i class="zmdi zmdi-account-add"></i>New User</a>
13 + @endif
12 </div> 14 </div>
13 </div> 15 </div>
14 </div> 16 </div>
...@@ -21,12 +23,22 @@ ...@@ -21,12 +23,22 @@
21 <th></th> 23 <th></th>
22 <th>Name</th> 24 <th>Name</th>
23 <th>Email</th> 25 <th>Email</th>
26 + <th>User Type</th>
24 </tr> 27 </tr>
25 @foreach($users as $user) 28 @foreach($users as $user)
26 <tr> 29 <tr>
27 <td style="line-height: 0;"><img class="avatar" src="{{$user->getAvatar(40)}}" alt="{{$user->name}}"></td> 30 <td style="line-height: 0;"><img class="avatar" src="{{$user->getAvatar(40)}}" alt="{{$user->name}}"></td>
28 - <td><a href="/users/{{$user->id}}">{{$user->name}}</a></td> 31 + <td>
32 + @if($currentUser->can('user-update') || $currentUser->id == $user->id)
33 + <a href="/users/{{$user->id}}">
34 + @endif
35 + {{$user->name}}
36 + @if($currentUser->can('user-update') || $currentUser->id == $user->id)
37 + </a>
38 + @endif
39 + </td>
29 <td>{{$user->email}}</td> 40 <td>{{$user->email}}</td>
41 + <td>{{ $user->role->display_name }}</td>
30 </tr> 42 </tr>
31 @endforeach 43 @endforeach
32 </table> 44 </table>
......