Fixed error on image deletion

Also Added tests to cover image upload and deletion.
Fixes #136.
This commit is contained in:
Dan Brown 2016-07-01 20:11:49 +01:00
parent 361ba8b244
commit 7b6c88f17c
7 changed files with 124 additions and 13 deletions

View File

@ -53,7 +53,7 @@ class ImageController extends Controller
]); ]);
$searchTerm = $request->get('term'); $searchTerm = $request->get('term');
$imgData = $this->imageRepo->searchPaginatedByType($type, $page,24, $searchTerm); $imgData = $this->imageRepo->searchPaginatedByType($type, $page, 24, $searchTerm);
return response()->json($imgData); return response()->json($imgData);
} }
@ -99,7 +99,7 @@ class ImageController extends Controller
{ {
$this->checkPermission('image-create-all'); $this->checkPermission('image-create-all');
$this->validate($request, [ $this->validate($request, [
'file' => 'image|mimes:jpeg,gif,png' 'file' => 'is_image'
]); ]);
$imageUpload = $request->file('file'); $imageUpload = $request->file('file');

View File

@ -15,7 +15,12 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function boot() 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);
});
} }
/** /**

View File

@ -4,6 +4,7 @@ use BookStack\Book;
use BookStack\Chapter; use BookStack\Chapter;
use BookStack\Entity; use BookStack\Entity;
use BookStack\JointPermission; use BookStack\JointPermission;
use BookStack\Ownable;
use BookStack\Page; use BookStack\Page;
use BookStack\Role; use BookStack\Role;
use BookStack\User; use BookStack\User;
@ -307,16 +308,16 @@ class PermissionService
/** /**
* Checks if an entity has a restriction set upon it. * Checks if an entity has a restriction set upon it.
* @param Entity $entity * @param Ownable $ownable
* @param $permission * @param $permission
* @return bool * @return bool
*/ */
public function checkEntityUserAccess(Entity $entity, $permission) public function checkOwnableUserAccess(Ownable $ownable, $permission)
{ {
if ($this->isAdmin) return true; if ($this->isAdmin) return true;
$explodedPermission = explode('-', $permission); $explodedPermission = explode('-', $permission);
$baseQuery = $entity->where('id', '=', $entity->id); $baseQuery = $ownable->where('id', '=', $ownable->id);
$action = end($explodedPermission); $action = end($explodedPermission);
$this->currentAction = $action; $this->currentAction = $action;
@ -327,7 +328,7 @@ class PermissionService
$allPermission = $this->currentUser && $this->currentUser->can($permission . '-all'); $allPermission = $this->currentUser && $this->currentUser->can($permission . '-all');
$ownPermission = $this->currentUser && $this->currentUser->can($permission . '-own'); $ownPermission = $this->currentUser && $this->currentUser->can($permission . '-own');
$this->currentAction = 'view'; $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)); return ($allPermission || ($isOwner && $ownPermission));
} }

View File

@ -1,5 +1,7 @@
<?php <?php
use BookStack\Ownable;
if (!function_exists('versioned_asset')) { if (!function_exists('versioned_asset')) {
/** /**
* Get the path to a versioned file. * Get the path to a versioned file.
@ -34,18 +36,18 @@ if (!function_exists('versioned_asset')) {
* If an ownable element is passed in the jointPermissions are checked against * If an ownable element is passed in the jointPermissions are checked against
* that particular item. * that particular item.
* @param $permission * @param $permission
* @param \BookStack\Ownable $ownable * @param Ownable $ownable
* @return mixed * @return mixed
*/ */
function userCan($permission, \BookStack\Ownable $ownable = null) function userCan($permission, Ownable $ownable = null)
{ {
if ($ownable === null) { if ($ownable === null) {
return auth()->user() && auth()->user()->can($permission); return auth()->user() && auth()->user()->can($permission);
} }
// Check permission on ownable item // Check permission on ownable item
$permissionService = app('BookStack\Services\PermissionService'); $permissionService = app(\BookStack\Services\PermissionService::class);
return $permissionService->checkEntityUserAccess($ownable, $permission); return $permissionService->checkOwnableUserAccess($ownable, $permission);
} }
/** /**

95
tests/ImageTest.php Normal file
View File

@ -0,0 +1,95 @@
<?php
class ImageTest extends TestCase
{
/**
* Get a test image that can be uploaded
* @param $fileName
* @return \Illuminate\Http\UploadedFile
*/
protected function getTestImage($fileName)
{
return new \Illuminate\Http\UploadedFile(base_path('tests/test-image.jpg'), $fileName, 'image/jpeg', 5238);
}
/**
* Get the path for a test image.
* @param $type
* @param $fileName
* @return string
*/
protected function getTestImagePath($type, $fileName)
{
return '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/' . $fileName;
}
/**
* Uploads an image with the given name.
* @param $name
* @param int $uploadedTo
* @return string
*/
protected function uploadImage($name, $uploadedTo = 0)
{
$file = $this->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');
}
}

View File

@ -39,11 +39,19 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
*/ */
public function asAdmin() public function asAdmin()
{ {
return $this->actingAs($this->getAdmin());
}
/**
* Get the current admin user.
* @return mixed
*/
public function getAdmin() {
if($this->admin === null) { if($this->admin === null) {
$adminRole = \BookStack\Role::getRole('admin'); $adminRole = \BookStack\Role::getRole('admin');
$this->admin = $adminRole->users->first(); $this->admin = $adminRole->users->first();
} }
return $this->actingAs($this->admin); return $this->admin;
} }
/** /**

BIN
tests/test-image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB