1
0
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:
Dan Brown
2021-08-28 21:48:17 +01:00
parent 82c6597a60
commit eda9e89c55
20 changed files with 196 additions and 36 deletions

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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.'])
)
);
}
/**