mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-30 04:23:11 +03:00
Added role permissions for exporting content
This commit is contained in:
@ -155,4 +155,17 @@ class BooksApiTest extends TestCase
|
||||
$resp->assertSee('# ' . $book->pages()->first()->name);
|
||||
$resp->assertSee('# ' . $book->chapters()->first()->name);
|
||||
}
|
||||
|
||||
public function test_cant_export_when_not_have_permission()
|
||||
{
|
||||
$types = ['html', 'plaintext', 'pdf', 'markdown'];
|
||||
$this->actingAsApiEditor();
|
||||
$this->removePermissionFromUser($this->getEditor(), 'content-export');
|
||||
|
||||
$book = Book::visible()->first();
|
||||
foreach ($types as $type) {
|
||||
$resp = $this->get($this->baseEndpoint . "/{$book->id}/export/{$type}");
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,4 +200,17 @@ class ChaptersApiTest extends TestCase
|
||||
$resp->assertSee('# ' . $chapter->name);
|
||||
$resp->assertSee('# ' . $chapter->pages()->first()->name);
|
||||
}
|
||||
|
||||
public function test_cant_export_when_not_have_permission()
|
||||
{
|
||||
$types = ['html', 'plaintext', 'pdf', 'markdown'];
|
||||
$this->actingAsApiEditor();
|
||||
$this->removePermissionFromUser($this->getEditor(), 'content-export');
|
||||
|
||||
$chapter = Chapter::visible()->has('pages')->first();
|
||||
foreach ($types as $type) {
|
||||
$resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/{$type}");
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,4 +292,17 @@ class PagesApiTest extends TestCase
|
||||
$resp->assertSee('# ' . $page->name);
|
||||
$resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.md"');
|
||||
}
|
||||
|
||||
public function test_cant_export_when_not_have_permission()
|
||||
{
|
||||
$types = ['html', 'plaintext', 'pdf', 'markdown'];
|
||||
$this->actingAsApiEditor();
|
||||
$this->removePermissionFromUser($this->getEditor(), 'content-export');
|
||||
|
||||
$page = Page::visible()->first();
|
||||
foreach ($types as $type) {
|
||||
$resp = $this->get($this->baseEndpoint . "/{$page->id}/export/{$type}");
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Entity;
|
||||
|
||||
use BookStack\Auth\Role;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Entities\Models\Page;
|
||||
@ -340,4 +341,29 @@ class ExportTest extends TestCase
|
||||
$resp->assertSee('# ' . $chapter->name);
|
||||
$resp->assertSee('# ' . $page->name);
|
||||
}
|
||||
|
||||
public function test_export_option_only_visible_and_accessible_with_permission()
|
||||
{
|
||||
$book = Book::query()->whereHas('pages')->whereHas('chapters')->first();
|
||||
$chapter = $book->chapters()->first();
|
||||
$page = $chapter->pages()->first();
|
||||
$entities = [$book, $chapter, $page];
|
||||
$user = $this->getViewer();
|
||||
$this->actingAs($user);
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$resp = $this->get($entity->getUrl());
|
||||
$resp->assertSee("/export/pdf");
|
||||
}
|
||||
|
||||
/** @var Role $role */
|
||||
$this->removePermissionFromUser($user, 'content-export');
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$resp = $this->get($entity->getUrl());
|
||||
$resp->assertDontSee("/export/pdf");
|
||||
$resp = $this->get($entity->getUrl("/export/pdf"));
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace Tests;
|
||||
|
||||
use BookStack\Auth\Permissions\PermissionService;
|
||||
use BookStack\Auth\Permissions\PermissionsRepo;
|
||||
use BookStack\Auth\Permissions\RolePermission;
|
||||
use BookStack\Auth\Role;
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Entities\Models\Book;
|
||||
@ -18,6 +19,7 @@ use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Settings\SettingService;
|
||||
use BookStack\Uploads\HttpFetcher;
|
||||
use Illuminate\Foundation\Testing\Assert as PHPUnit;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Env;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Mockery;
|
||||
@ -184,6 +186,19 @@ trait SharedTestHelpers
|
||||
$user->clearPermissionCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely remove the given permission name from the given user.
|
||||
*/
|
||||
protected function removePermissionFromUser(User $user, string $permission)
|
||||
{
|
||||
$permission = RolePermission::query()->where('name', '=', $permission)->first();
|
||||
/** @var Role $role */
|
||||
foreach ($user->roles as $role) {
|
||||
$role->detachPermission($permission);
|
||||
}
|
||||
$user->clearPermissionCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new basic role for testing purposes.
|
||||
*/
|
||||
@ -274,8 +289,17 @@ trait SharedTestHelpers
|
||||
private function isPermissionError($response): bool
|
||||
{
|
||||
return $response->status() === 302
|
||||
&& $response->headers->get('Location') === url('/')
|
||||
&& strpos(session()->pull('error', ''), 'You do not have permission to access') === 0;
|
||||
&& (
|
||||
(
|
||||
$response->headers->get('Location') === url('/')
|
||||
&& strpos(session()->pull('error', ''), 'You do not have permission to access') === 0
|
||||
)
|
||||
||
|
||||
(
|
||||
$response instanceof JsonResponse &&
|
||||
$response->json(['error' => 'You do not have permission to perform the requested action.'])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user