mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-07-15 21:31:36 +03:00
Images: Increased validation against related page on upload
Adds validation that the related page exists, is visible, and that the user has page edit permissions for the page. Aligns with attachment permission model, and aligns across different image endpoints. Added tests to cover. Closes #6126
This commit is contained in:
@@ -81,7 +81,6 @@ return [
|
||||
'strict' => false,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
// @phpstan-ignore class.notFound
|
||||
(PHP_VERSION_ID >= 80500 ? \Pdo\Mysql::ATTR_SSL_CA : \PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
|
||||
]) : [],
|
||||
],
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace BookStack\Uploads\Controllers;
|
||||
|
||||
use BookStack\Entities\Queries\PageQueries;
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Http\Controller;
|
||||
use BookStack\Permissions\Permission;
|
||||
@@ -14,7 +15,8 @@ use Illuminate\Http\Request;
|
||||
class DrawioImageController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected ImageRepo $imageRepo
|
||||
protected ImageRepo $imageRepo,
|
||||
protected PageQueries $pageQueries,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -53,16 +55,18 @@ class DrawioImageController extends Controller
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
$this->checkPermission(Permission::ImageCreateAll);
|
||||
$validated = $this->validate($request, [
|
||||
'image' => ['required', 'string'],
|
||||
'uploaded_to' => ['required', 'integer'],
|
||||
]);
|
||||
|
||||
$this->checkPermission(Permission::ImageCreateAll);
|
||||
$imageBase64Data = $request->input('image');
|
||||
$imageBase64Data = $validated['image'];
|
||||
$uploadedTo = $validated['uploaded_to'];
|
||||
$targetPage = $this->pageQueries->findVisibleByIdOrFail($uploadedTo);
|
||||
$this->checkOwnablePermission(Permission::PageUpdate, $targetPage);
|
||||
|
||||
try {
|
||||
$uploadedTo = $request->input('uploaded_to', 0);
|
||||
$image = $this->imageRepo->saveDrawing($imageBase64Data, $uploadedTo);
|
||||
} catch (ImageUploadException $e) {
|
||||
return response($e->getMessage(), 500);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace BookStack\Uploads\Controllers;
|
||||
|
||||
use BookStack\Entities\Queries\PageQueries;
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Http\Controller;
|
||||
use BookStack\Permissions\Permission;
|
||||
@@ -14,7 +15,8 @@ use Illuminate\Validation\ValidationException;
|
||||
class GalleryImageController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected ImageRepo $imageRepo
|
||||
protected ImageRepo $imageRepo,
|
||||
protected PageQueries $pageQueries,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -56,20 +58,26 @@ class GalleryImageController extends Controller
|
||||
$this->checkPermission(Permission::ImageCreateAll);
|
||||
|
||||
try {
|
||||
$this->validate($request, [
|
||||
$validated = $this->validate($request, [
|
||||
'file' => $this->getImageValidationRules(),
|
||||
'uploaded_to' => ['required', 'integer'],
|
||||
]);
|
||||
} catch (ValidationException $exception) {
|
||||
return $this->jsonError(implode("\n", $exception->errors()['file']));
|
||||
$errors = $exception->errors();
|
||||
$messages = array_merge($errors['file'] ?? [], $errors['uploaded_to'] ?? []);
|
||||
return $this->jsonError(implode("\n", $messages));
|
||||
}
|
||||
|
||||
$uploadedTo = intval($validated['uploaded_to']);
|
||||
$targetPage = $this->pageQueries->findVisibleByIdOrFail($uploadedTo);
|
||||
$this->checkOwnablePermission(Permission::PageUpdate, $targetPage);
|
||||
|
||||
new OutOfMemoryHandler(function () {
|
||||
return $this->jsonError(trans('errors.image_upload_memory_limit'));
|
||||
});
|
||||
|
||||
try {
|
||||
$imageUpload = $request->file('file');
|
||||
$uploadedTo = $request->input('uploaded_to', 0);
|
||||
$imageUpload = $validated['file'];
|
||||
$image = $this->imageRepo->saveNew($imageUpload, 'gallery', $uploadedTo);
|
||||
} catch (ImageUploadException $e) {
|
||||
return response($e->getMessage(), 500);
|
||||
|
||||
@@ -75,6 +75,7 @@ class ImageGalleryApiController extends ApiController
|
||||
$this->checkPermission(Permission::ImageCreateAll);
|
||||
$data = $this->validate($request, $this->rules()['create']);
|
||||
$page = $this->pageQueries->findVisibleByIdOrFail($data['uploaded_to']);
|
||||
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||
|
||||
$image = $this->imageRepo->saveNew($data['image'], $data['type'], $page->id);
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class CommentMentionTest extends TestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $userA->roles()->first());
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $userA->roles()->first());
|
||||
|
||||
$this->asAdmin()->post("/comment/{$page->id}", [
|
||||
'html' => '<p>Hello <a data-mention-user-id="' . $userA->id . '"></a> and <a data-mention-user-id="' . $userB->id . '"></a></p>'
|
||||
|
||||
@@ -39,7 +39,7 @@ class ContentPermissionsApiTest extends TestCase
|
||||
$page = $this->entities->page();
|
||||
$owner = $this->users->newUser();
|
||||
$role = $this->users->createRole();
|
||||
$this->permissions->addEntityPermission($page, ['view', 'delete'], $role);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view', 'delete'], $role);
|
||||
$this->permissions->changeEntityOwner($page, $owner);
|
||||
$this->permissions->setFallbackPermissions($page, ['update', 'create']);
|
||||
|
||||
@@ -209,7 +209,7 @@ class ContentPermissionsApiTest extends TestCase
|
||||
public function test_update_can_clear_roles_permissions()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->addEntityPermission($page, ['view'], $this->users->createRole());
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $this->users->createRole());
|
||||
$page->owned_by = null;
|
||||
$page->save();
|
||||
|
||||
|
||||
@@ -154,6 +154,34 @@ class ImageGalleryApiTest extends TestCase
|
||||
$resp->assertStatus(404);
|
||||
}
|
||||
|
||||
public function test_create_requires_update_permission_for_the_target_page()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->actingAsForApi($editor);
|
||||
|
||||
$makeRequest = function (int $uploadedTo) {
|
||||
return $this->call('POST', $this->baseEndpoint, [
|
||||
'type' => 'gallery',
|
||||
'uploaded_to' => $uploadedTo,
|
||||
'name' => 'My awesome image!',
|
||||
], [], [
|
||||
'image' => $this->files->uploadedImage('my-cool-image.png'),
|
||||
]);
|
||||
};
|
||||
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $editor->roles()->first());
|
||||
|
||||
$resp = $makeRequest($page->id);
|
||||
$resp->assertStatus(403);
|
||||
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view', 'update'], $editor->roles()->first());
|
||||
|
||||
$resp = $makeRequest($page->id);
|
||||
$resp->assertStatus(200);
|
||||
}
|
||||
|
||||
public function test_create_has_restricted_types()
|
||||
{
|
||||
$this->actingAsApiEditor();
|
||||
|
||||
@@ -16,7 +16,7 @@ class RegeneratePermissionsCommandTest extends TestCase
|
||||
$page = $this->entities->page();
|
||||
$editor = $this->users->editor();
|
||||
$role = $editor->roles()->first();
|
||||
$this->permissions->addEntityPermission($page, ['view'], $role);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $role);
|
||||
JointPermission::query()->truncate();
|
||||
|
||||
$this->assertDatabaseMissing('joint_permissions', ['entity_id' => $page->id]);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ErrorTest extends TestCase
|
||||
@@ -44,7 +43,7 @@ class ErrorTest extends TestCase
|
||||
$this->actingAs($editor)->get($page->getUrl())->assertOk();
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($book);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $editor->roles()->first());
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $editor->roles()->first());
|
||||
|
||||
$resp = $this->actingAs($editor)->get($book->getUrl());
|
||||
$resp->assertNotFound();
|
||||
|
||||
@@ -101,8 +101,9 @@ class PermissionsProvider
|
||||
$this->addEntityPermissionEntries($entity, $permissions);
|
||||
}
|
||||
|
||||
public function addEntityPermission(Entity $entity, array $actionList, Role $role)
|
||||
public function setEntityPermissionsForRole(Entity $entity, array $actionList, Role $role)
|
||||
{
|
||||
$entity->permissions()->where('role_id', '=', $role->id)->delete();
|
||||
$permissionData = $this->actionListToEntityPermissionData($actionList, $role->id);
|
||||
$this->addEntityPermissionEntries($entity, [$permissionData]);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleB);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -67,8 +67,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleB);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -80,8 +80,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -93,8 +93,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -107,8 +107,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleB);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -121,8 +121,8 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($chapter);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleA);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleB);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
{
|
||||
[$user, $roleA] = $this->users->newUserWithRole();
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
{
|
||||
[$user, $roleA] = $this->users->newUserWithRole([], ['page-view-all']);
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
[$user, $roleA] = $this->users->newUserWithRole([], []);
|
||||
$page = $this->entities->pageWithinChapter();
|
||||
$chapter = $page->chapter;
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
[$user, $roleA] = $this->users->newUserWithRole([], ['page-view-all']);
|
||||
$page = $this->entities->pageWithinChapter();
|
||||
$chapter = $page->chapter;
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -170,7 +170,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
[$user, $roleA] = $this->users->newUserWithRole([], ['page-view-own']);
|
||||
$page = $this->entities->pageWithinChapter();
|
||||
$chapter = $page->chapter;
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
$this->permissions->changeEntityOwner($page, $user);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
@@ -182,7 +182,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$roleB = $this->users->attachNewRole($user);
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->addEntityPermission($page, [], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleB);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -194,7 +194,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->changeEntityOwner($page, $user);
|
||||
|
||||
$this->permissions->addEntityPermission($page, [], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleB);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -207,7 +207,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->pageWithinChapter();
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleB);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -220,7 +220,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
$this->permissions->changeEntityOwner($page, $user);
|
||||
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleB);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleB);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -231,7 +231,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->setFallbackPermissions($page, []);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -241,7 +241,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->setFallbackPermissions($page, ['view']);
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -253,7 +253,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->setFallbackPermissions($page, []);
|
||||
$this->permissions->addEntityPermission($page, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -265,7 +265,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->permissions->setFallbackPermissions($page, ['view']);
|
||||
$this->permissions->addEntityPermission($page, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($page, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->setFallbackPermissions($chapter, []);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -289,7 +289,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->setFallbackPermissions($chapter, ['view']);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -302,7 +302,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->setFallbackPermissions($chapter, []);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -315,7 +315,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
$chapter = $page->chapter;
|
||||
|
||||
$this->permissions->setFallbackPermissions($chapter, ['view']);
|
||||
$this->permissions->addEntityPermission($chapter, [], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, [], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
|
||||
$this->permissions->setFallbackPermissions($chapter, []);
|
||||
$this->permissions->setFallbackPermissions($page, []);
|
||||
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($chapter, ['view'], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
@@ -342,7 +342,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
|
||||
|
||||
$this->permissions->setFallbackPermissions($book, []);
|
||||
$this->permissions->setFallbackPermissions($chapter, []);
|
||||
$this->permissions->addEntityPermission($book, ['view'], $roleA);
|
||||
$this->permissions->setEntityPermissionsForRole($book, ['view'], $roleA);
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Permissions\Models\RolePermission;
|
||||
use BookStack\Users\Models\Role;
|
||||
use BookStack\Users\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
@@ -173,7 +172,7 @@ class PublicActionTest extends TestCase
|
||||
$newRole = $this->users->attachNewRole($this->users->guest(), []);
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
$this->permissions->addEntityPermission($page, ['view', 'update'], $newRole);
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view', 'update'], $newRole);
|
||||
|
||||
$resp = $this->get($page->getUrl());
|
||||
$resp->assertOk();
|
||||
|
||||
@@ -72,6 +72,30 @@ class DrawioTest extends TestCase
|
||||
$this->assertTrue($testImageData === $uploadedImageData, 'Uploaded image file data does not match our test image as expected');
|
||||
}
|
||||
|
||||
public function test_base64_upload_requires_edit_permission_to_page()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$editor = $this->users->editor();
|
||||
$this->actingAs($editor);
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
|
||||
$upload = function () use ($page) {
|
||||
return $this->postJson('images/drawio', [
|
||||
'uploaded_to' => $page->id,
|
||||
'image' => 'image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEcDCo5iYNs+gAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFElEQVQI12O0jN/KgASYGFABqXwAZtoBV6Sl3hIAAAAASUVORK5CYII=',
|
||||
]);
|
||||
};
|
||||
|
||||
$upload()->assertStatus(404);
|
||||
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $editor->roles()->first());
|
||||
$upload()->assertStatus(403);
|
||||
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view', 'update'], $editor->roles()->first());
|
||||
$upload()->assertStatus(200);
|
||||
}
|
||||
|
||||
public function test_drawio_url_can_be_configured()
|
||||
{
|
||||
config()->set('services.drawio', 'http://cats.com?dog=tree');
|
||||
|
||||
@@ -36,6 +36,45 @@ class ImageTest extends TestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_image_upload_with_page_reference_requires_visibility_and_update_permissions_of_target_page()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$editor = $this->users->editor();
|
||||
|
||||
$this->permissions->disableEntityInheritedPermissions($page);
|
||||
$this->actingAs($editor);
|
||||
|
||||
$resp = $this->files->uploadGalleryImage($this, 'test-image.png', $page->id);
|
||||
$resp->assertStatus(404);
|
||||
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view'], $editor->roles()->first());
|
||||
|
||||
$resp = $this->files->uploadGalleryImage($this, 'test-image.png', $page->id);
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$this->permissions->setEntityPermissionsForRole($page, ['view', 'update'], $editor->roles()->first());
|
||||
|
||||
$resp = $this->files->uploadGalleryImage($this, 'test-image.png', $page->id);
|
||||
$resp->assertStatus(200);
|
||||
|
||||
$this->files->deleteAtRelativePath($resp->json('path'));
|
||||
}
|
||||
|
||||
public function test_image_upload_with_page_reference_requires_page_to_exist()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
$this->entities->destroy($page);
|
||||
|
||||
$editor = $this->users->editor();
|
||||
$this->actingAs($editor);
|
||||
|
||||
$resp = $this->files->uploadGalleryImage($this, 'test-image.png', $page->id);
|
||||
$resp->assertStatus(404);
|
||||
|
||||
$resp = $this->files->uploadGalleryImage($this, 'test-image.png', 0);
|
||||
$resp->assertStatus(404);
|
||||
}
|
||||
|
||||
public function test_image_display_thumbnail_generation_does_not_increase_image_size()
|
||||
{
|
||||
$page = $this->entities->page();
|
||||
|
||||
Reference in New Issue
Block a user