}
/**
- * Checks if a user has a book or chapter available to create a page
- * @param Ownable $ownable
- * @param $permission
+ * Checks if a user has the given permission for any items in the system.
+ * @param string $permission
* @return bool
*/
- public function checkAvailableCreatePageAccess()
+ public function checkUserHasPermissionOnAnything(string $permission)
{
- $userRoleIds = $this->currentUser()->roles()->pluck('id')->toArray();
+ $userRoleIds = $this->currentUser()->roles()->select('id')->pluck('id')->toArray();
$userId = $this->currentUser()->id;
-
$canCreatePage = $this->db->table('joint_permissions')
- ->where('action', '=', 'page-create')
+ ->where('action', '=', $permission)
->whereIn('role_id', $userRoleIds)
->where(function ($query) use ($userId) {
$query->where('has_permission', '=', 1)
})
->get()->count() > 0;
+ $this->clean();
return $canCreatePage;
}
<?php
+use BookStack\Auth\Permissions\PermissionService;
use BookStack\Ownable;
/**
* Check if the current user has a permission.
* If an ownable element is passed in the jointPermissions are checked against
* that particular item.
- * @param $permission
+ * @param string $permission
* @param Ownable $ownable
* @return mixed
*/
-function userCan($permission, Ownable $ownable = null)
+function userCan(string $permission, Ownable $ownable = null)
{
if ($ownable === null) {
return user() && user()->can($permission);
}
// Check permission on ownable item
- $permissionService = app(\BookStack\Auth\Permissions\PermissionService::class);
+ $permissionService = app(PermissionService::class);
return $permissionService->checkOwnableUserAccess($ownable, $permission);
}
/**
- * Check if the current user has the ability to create a page for an existing object
+ * Check if the current user has the given permission
+ * on any item in the system.
+ * @param string $permission
* @return bool
*/
-function userCanCreatePage()
+function userCanOnAny(string $permission)
{
- // Check for create page permissions
- $permissionService = app(\BookStack\Auth\Permissions\PermissionService::class);
- return $permissionService->checkAvailableCreatePageAccess();
+ $permissionService = app(PermissionService::class);
+ return $permissionService->checkUserHasPermissionOnAnything($permission);
}
/**
@if(userCan('page-update', $page))
<a href="{{ $page->getUrl('/edit') }}" class="text-primary text-button" >@icon('edit'){{ trans('common.edit') }}</a>
@endif
- @if((userCan('page-view', $page) && userCanCreatePage()) || userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page))
+ @if((userCan('page-view', $page) && userCanOnAny('page-create')) || userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page))
<div dropdown class="dropdown-container">
<a dropdown-toggle class="text-primary text-button">@icon('more') {{ trans('common.more') }}</a>
<ul>
- @if(userCanCreatePage())
+ @if(userCanOnAny('page-create'))
<li><a href="{{ $page->getUrl('/copy') }}" class="text-primary" >@icon('copy'){{ trans('common.copy') }}</a></li>
@endif
- @if(userCan('page-delete', $page) && userCan('page-update, $page))
+ @if(userCan('page-delete', $page) && userCan('page-update', $page))
<li><a href="{{ $page->getUrl('/move') }}" class="text-primary" >@icon('folder'){{ trans('common.move') }}</a></li>
@endif
@if(userCan('page-update', $page))
<?php namespace Tests;
+use BookStack\Auth\Role;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
$this->assertTrue($pageCopy->id !== $page->id, 'Page copy is not the same instance');
}
+ public function test_page_can_be_copied_without_edit_permission()
+ {
+ $page = Page::first();
+ $currentBook = $page->book;
+ $newBook = Book::where('id', '!=', $currentBook->id)->first();
+ $viewer = $this->getViewer();
+
+ $resp = $this->actingAs($viewer)->get($page->getUrl());
+ $resp->assertDontSee($page->getUrl('/copy'));
+
+ $newBook->created_by = $viewer->id;
+ $newBook->save();
+ $this->giveUserPermissions($viewer, ['page-create-own']);
+ $this->regenEntityPermissions($newBook);
+
+ $resp = $this->actingAs($viewer)->get($page->getUrl());
+ $resp->assertSee($page->getUrl('/copy'));
+
+ $movePageResp = $this->post($page->getUrl('/copy'), [
+ 'entity_selection' => 'book:' . $newBook->id,
+ 'name' => 'My copied test page'
+ ]);
+ $movePageResp->assertRedirect();
+
+ $this->assertDatabaseHas('pages', [
+ 'name' => 'My copied test page',
+ 'created_by' => $viewer->id,
+ 'book_id' => $newBook->id,
+ ]);
+ }
+
}
\ No newline at end of file