diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php index 2e5d5f303..621c23e85 100644 --- a/app/Http/Controllers/ImageController.php +++ b/app/Http/Controllers/ImageController.php @@ -51,9 +51,9 @@ class ImageController extends Controller $this->validate($request, [ 'term' => 'required|string' ]); - + $searchTerm = $request->get('term'); - $imgData = $this->imageRepo->searchPaginatedByType($type, $page,24, $searchTerm); + $imgData = $this->imageRepo->searchPaginatedByType($type, $page, 24, $searchTerm); return response()->json($imgData); } @@ -99,7 +99,7 @@ class ImageController extends Controller { $this->checkPermission('image-create-all'); $this->validate($request, [ - 'file' => 'image|mimes:jpeg,gif,png' + 'file' => 'is_image' ]); $imageUpload = $request->file('file'); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8bcbcbdad..f214c9141 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -15,7 +15,12 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // + // Custom validation methods + \Validator::extend('is_image', function($attribute, $value, $parameters, $validator) { + $imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/tiff', 'image/webp']; + return in_array($value->getMimeType(), $imageMimes); + }); + } /** diff --git a/app/Services/PermissionService.php b/app/Services/PermissionService.php index 218cb30a5..0fffe60f2 100644 --- a/app/Services/PermissionService.php +++ b/app/Services/PermissionService.php @@ -4,6 +4,7 @@ use BookStack\Book; use BookStack\Chapter; use BookStack\Entity; use BookStack\JointPermission; +use BookStack\Ownable; use BookStack\Page; use BookStack\Role; use BookStack\User; @@ -307,16 +308,16 @@ class PermissionService /** * Checks if an entity has a restriction set upon it. - * @param Entity $entity + * @param Ownable $ownable * @param $permission * @return bool */ - public function checkEntityUserAccess(Entity $entity, $permission) + public function checkOwnableUserAccess(Ownable $ownable, $permission) { if ($this->isAdmin) return true; $explodedPermission = explode('-', $permission); - $baseQuery = $entity->where('id', '=', $entity->id); + $baseQuery = $ownable->where('id', '=', $ownable->id); $action = end($explodedPermission); $this->currentAction = $action; @@ -327,7 +328,7 @@ class PermissionService $allPermission = $this->currentUser && $this->currentUser->can($permission . '-all'); $ownPermission = $this->currentUser && $this->currentUser->can($permission . '-own'); $this->currentAction = 'view'; - $isOwner = $this->currentUser && $this->currentUser->id === $entity->created_by; + $isOwner = $this->currentUser && $this->currentUser->id === $ownable->created_by; return ($allPermission || ($isOwner && $ownPermission)); } diff --git a/app/helpers.php b/app/helpers.php index b8f61d94e..42e4c1894 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,7 @@ user() && auth()->user()->can($permission); } // Check permission on ownable item - $permissionService = app('BookStack\Services\PermissionService'); - return $permissionService->checkEntityUserAccess($ownable, $permission); + $permissionService = app(\BookStack\Services\PermissionService::class); + return $permissionService->checkOwnableUserAccess($ownable, $permission); } /** diff --git a/tests/ImageTest.php b/tests/ImageTest.php new file mode 100644 index 000000000..806a36acc --- /dev/null +++ b/tests/ImageTest.php @@ -0,0 +1,95 @@ +getTestImage($name); + $this->call('POST', '/images/gallery/upload', ['uploaded_to' => $uploadedTo], [], ['file' => $file], []); + return $this->getTestImagePath('gallery', $name); + } + + /** + * Delete an uploaded image. + * @param $relPath + */ + protected function deleteImage($relPath) + { + unlink(public_path($relPath)); + } + + + public function test_image_upload() + { + $page = \BookStack\Page::first(); + $this->asAdmin(); + $admin = $this->getAdmin(); + $imageName = 'first-image.jpg'; + + $relPath = $this->uploadImage($imageName, $page->id); + $this->assertResponseOk(); + + $this->assertTrue(file_exists(public_path($relPath)), 'Uploaded image exists'); + + $this->seeInDatabase('images', [ + 'url' => $relPath, + 'type' => 'gallery', + 'uploaded_to' => $page->id, + 'path' => $relPath, + 'created_by' => $admin->id, + 'updated_by' => $admin->id, + 'name' => $imageName + ]); + + $this->deleteImage($relPath); + } + + public function test_image_delete() + { + $page = \BookStack\Page::first(); + $this->asAdmin(); + $imageName = 'first-image.jpg'; + + $relPath = $this->uploadImage($imageName, $page->id); + $image = \BookStack\Image::first(); + + $this->call('DELETE', '/images/' . $image->id); + $this->assertResponseOk(); + + $this->dontSeeInDatabase('images', [ + 'url' => $relPath, + 'type' => 'gallery' + ]); + + $this->assertFalse(file_exists(public_path($relPath)), 'Uploaded image has been deleted'); + } + +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index 4c2893f4e..6a8c2d732 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -39,11 +39,19 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase */ public function asAdmin() { + return $this->actingAs($this->getAdmin()); + } + + /** + * Get the current admin user. + * @return mixed + */ + public function getAdmin() { if($this->admin === null) { $adminRole = \BookStack\Role::getRole('admin'); $this->admin = $adminRole->users->first(); } - return $this->actingAs($this->admin); + return $this->admin; } /** diff --git a/tests/test-image.jpg b/tests/test-image.jpg new file mode 100644 index 000000000..fb8da9101 Binary files /dev/null and b/tests/test-image.jpg differ