mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-10-23 18:48:37 +03:00
Merge pull request #5793 from BookStackApp/role_permission_refactor
Permissions: Use of enum references and RolePermission cleanup
This commit is contained in:
@@ -9,6 +9,7 @@ use BookStack\Exceptions\LoginAttemptInvalidUserException;
|
|||||||
use BookStack\Exceptions\StoppedAuthenticationException;
|
use BookStack\Exceptions\StoppedAuthenticationException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
use BookStack\Facades\Theme;
|
use BookStack\Facades\Theme;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Theming\ThemeEvents;
|
use BookStack\Theming\ThemeEvents;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -50,7 +51,7 @@ class LoginService
|
|||||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, $method, $user);
|
Theme::dispatch(ThemeEvents::AUTH_LOGIN, $method, $user);
|
||||||
|
|
||||||
// Authenticate on all session guards if a likely admin
|
// Authenticate on all session guards if a likely admin
|
||||||
if ($user->can('users-manage') && $user->can('user-roles-manage')) {
|
if ($user->can(Permission::UsersManage) && $user->can(Permission::UserRolesManage)) {
|
||||||
$guards = ['standard', 'ldap', 'saml2', 'oidc'];
|
$guards = ['standard', 'ldap', 'saml2', 'oidc'];
|
||||||
foreach ($guards as $guard) {
|
foreach ($guards as $guard) {
|
||||||
auth($guard)->login($user);
|
auth($guard)->login($user);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Activity\Controllers;
|
|||||||
|
|
||||||
use BookStack\Activity\Models\Activity;
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class AuditLogApiController extends ApiController
|
class AuditLogApiController extends ApiController
|
||||||
{
|
{
|
||||||
@@ -16,8 +17,8 @@ class AuditLogApiController extends ApiController
|
|||||||
*/
|
*/
|
||||||
public function list()
|
public function list()
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$query = Activity::query()->with(['user']);
|
$query = Activity::query()->with(['user']);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace BookStack\Activity\Controllers;
|
|||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Activity\Models\Activity;
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Sorting\SortUrl;
|
use BookStack\Sorting\SortUrl;
|
||||||
use BookStack\Util\SimpleListOptions;
|
use BookStack\Util\SimpleListOptions;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -13,8 +14,8 @@ class AuditLogController extends Controller
|
|||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$sort = $request->get('sort', 'activity_date');
|
$sort = $request->get('sort', 'activity_date');
|
||||||
$order = $request->get('order', 'desc');
|
$order = $request->get('order', 'desc');
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Activity\Tools\CommentTree;
|
|||||||
use BookStack\Activity\Tools\CommentTreeNode;
|
use BookStack\Activity\Tools\CommentTreeNode;
|
||||||
use BookStack\Entities\Queries\PageQueries;
|
use BookStack\Entities\Queries\PageQueries;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ class CommentController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new comment.
|
// Create a new comment.
|
||||||
$this->checkPermission('comment-create-all');
|
$this->checkPermission(Permission::CommentCreateAll);
|
||||||
$contentRef = $input['content_ref'] ?? '';
|
$contentRef = $input['content_ref'] ?? '';
|
||||||
$comment = $this->commentRepo->create($page, $input['html'], $input['parent_id'] ?? null, $contentRef);
|
$comment = $this->commentRepo->create($page, $input['html'], $input['parent_id'] ?? null, $contentRef);
|
||||||
|
|
||||||
@@ -64,8 +65,8 @@ class CommentController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$comment = $this->commentRepo->getById($commentId);
|
$comment = $this->commentRepo->getById($commentId);
|
||||||
$this->checkOwnablePermission('page-view', $comment->entity);
|
$this->checkOwnablePermission(Permission::PageView, $comment->entity);
|
||||||
$this->checkOwnablePermission('comment-update', $comment);
|
$this->checkOwnablePermission(Permission::CommentUpdate, $comment);
|
||||||
|
|
||||||
$comment = $this->commentRepo->update($comment, $input['html']);
|
$comment = $this->commentRepo->update($comment, $input['html']);
|
||||||
|
|
||||||
@@ -81,8 +82,8 @@ class CommentController extends Controller
|
|||||||
public function archive(int $id)
|
public function archive(int $id)
|
||||||
{
|
{
|
||||||
$comment = $this->commentRepo->getById($id);
|
$comment = $this->commentRepo->getById($id);
|
||||||
$this->checkOwnablePermission('page-view', $comment->entity);
|
$this->checkOwnablePermission(Permission::PageView, $comment->entity);
|
||||||
if (!userCan('comment-update', $comment) && !userCan('comment-delete', $comment)) {
|
if (!userCan(Permission::CommentUpdate, $comment) && !userCan(Permission::CommentDelete, $comment)) {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +102,8 @@ class CommentController extends Controller
|
|||||||
public function unarchive(int $id)
|
public function unarchive(int $id)
|
||||||
{
|
{
|
||||||
$comment = $this->commentRepo->getById($id);
|
$comment = $this->commentRepo->getById($id);
|
||||||
$this->checkOwnablePermission('page-view', $comment->entity);
|
$this->checkOwnablePermission(Permission::PageView, $comment->entity);
|
||||||
if (!userCan('comment-update', $comment) && !userCan('comment-delete', $comment)) {
|
if (!userCan(Permission::CommentUpdate, $comment) && !userCan(Permission::CommentDelete, $comment)) {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +122,7 @@ class CommentController extends Controller
|
|||||||
public function destroy(int $id)
|
public function destroy(int $id)
|
||||||
{
|
{
|
||||||
$comment = $this->commentRepo->getById($id);
|
$comment = $this->commentRepo->getById($id);
|
||||||
$this->checkOwnablePermission('comment-delete', $comment);
|
$this->checkOwnablePermission(Permission::CommentDelete, $comment);
|
||||||
|
|
||||||
$this->commentRepo->delete($comment);
|
$this->commentRepo->delete($comment);
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ namespace BookStack\Activity\Controllers;
|
|||||||
use BookStack\Activity\Tools\UserEntityWatchOptions;
|
use BookStack\Activity\Tools\UserEntityWatchOptions;
|
||||||
use BookStack\Entities\Tools\MixedEntityRequestHelper;
|
use BookStack\Entities\Tools\MixedEntityRequestHelper;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class WatchController extends Controller
|
class WatchController extends Controller
|
||||||
{
|
{
|
||||||
public function update(Request $request, MixedEntityRequestHelper $entityHelper)
|
public function update(Request $request, MixedEntityRequestHelper $entityHelper)
|
||||||
{
|
{
|
||||||
$this->checkPermission('receive-notifications');
|
$this->checkPermission(Permission::ReceiveNotifications);
|
||||||
$this->preventGuestAccess();
|
$this->preventGuestAccess();
|
||||||
|
|
||||||
$requestData = $this->validate($request, array_merge([
|
$requestData = $this->validate($request, array_merge([
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Activity\ActivityType;
|
|||||||
use BookStack\Activity\Models\Webhook;
|
use BookStack\Activity\Models\Webhook;
|
||||||
use BookStack\Activity\Queries\WebhooksAllPaginatedAndSorted;
|
use BookStack\Activity\Queries\WebhooksAllPaginatedAndSorted;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Util\SimpleListOptions;
|
use BookStack\Util\SimpleListOptions;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ class WebhookController extends Controller
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware([
|
$this->middleware([
|
||||||
'can:settings-manage',
|
Permission::SettingsManage->middleware()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace BookStack\Activity\Notifications\Handlers;
|
|||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
|
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
|
||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Permissions\PermissionApplicator;
|
use BookStack\Permissions\PermissionApplicator;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -26,7 +27,7 @@ abstract class BaseNotificationHandler implements NotificationHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prevent sending of the user does not have notification permissions
|
// Prevent sending of the user does not have notification permissions
|
||||||
if (!$user->can('receive-notifications')) {
|
if (!$user->can(Permission::ReceiveNotifications)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Activity\Tools;
|
|||||||
|
|
||||||
use BookStack\Activity\Models\Comment;
|
use BookStack\Activity\Models\Comment;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class CommentTree
|
class CommentTree
|
||||||
{
|
{
|
||||||
@@ -70,7 +71,7 @@ class CommentTree
|
|||||||
public function canUpdateAny(): bool
|
public function canUpdateAny(): bool
|
||||||
{
|
{
|
||||||
foreach ($this->comments as $comment) {
|
foreach ($this->comments as $comment) {
|
||||||
if (userCan('comment-update', $comment)) {
|
if (userCan(Permission::CommentUpdate, $comment)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Activity\Models\Tag;
|
|||||||
use BookStack\Entities\Models\BookChild;
|
use BookStack\Entities\Models\BookChild;
|
||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class TagClassGenerator
|
class TagClassGenerator
|
||||||
{
|
{
|
||||||
@@ -26,14 +27,14 @@ class TagClassGenerator
|
|||||||
array_push($classes, ...$this->generateClassesForTag($tag));
|
array_push($classes, ...$this->generateClassesForTag($tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->entity instanceof BookChild && userCan('view', $this->entity->book)) {
|
if ($this->entity instanceof BookChild && userCan(Permission::BookView, $this->entity->book)) {
|
||||||
$bookTags = $this->entity->book->tags;
|
$bookTags = $this->entity->book->tags;
|
||||||
foreach ($bookTags as $bookTag) {
|
foreach ($bookTags as $bookTag) {
|
||||||
array_push($classes, ...$this->generateClassesForTag($bookTag, 'book-'));
|
array_push($classes, ...$this->generateClassesForTag($bookTag, 'book-'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->entity instanceof Page && $this->entity->chapter && userCan('view', $this->entity->chapter)) {
|
if ($this->entity instanceof Page && $this->entity->chapter && userCan(Permission::ChapterView, $this->entity->chapter)) {
|
||||||
$chapterTags = $this->entity->chapter->tags;
|
$chapterTags = $this->entity->chapter->tags;
|
||||||
foreach ($chapterTags as $chapterTag) {
|
foreach ($chapterTags as $chapterTag) {
|
||||||
array_push($classes, ...$this->generateClassesForTag($chapterTag, 'chapter-'));
|
array_push($classes, ...$this->generateClassesForTag($chapterTag, 'chapter-'));
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Activity\WatchLevels;
|
|||||||
use BookStack\Entities\Models\BookChild;
|
use BookStack\Entities\Models\BookChild;
|
||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ class UserEntityWatchOptions
|
|||||||
|
|
||||||
public function canWatch(): bool
|
public function canWatch(): bool
|
||||||
{
|
{
|
||||||
return $this->user->can('receive-notifications') && !$this->user->isGuest();
|
return $this->user->can(Permission::ReceiveNotifications) && !$this->user->isGuest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWatchLevel(): string
|
public function getWatchLevel(): string
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Api;
|
|||||||
|
|
||||||
use BookStack\Access\LoginService;
|
use BookStack\Access\LoginService;
|
||||||
use BookStack\Exceptions\ApiAuthException;
|
use BookStack\Exceptions\ApiAuthException;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Auth\GuardHelpers;
|
use Illuminate\Auth\GuardHelpers;
|
||||||
use Illuminate\Contracts\Auth\Authenticatable;
|
use Illuminate\Contracts\Auth\Authenticatable;
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
use Illuminate\Contracts\Auth\Guard;
|
||||||
@@ -146,7 +147,7 @@ class ApiTokenGuard implements Guard
|
|||||||
throw new ApiAuthException(trans('errors.api_user_token_expired'), 403);
|
throw new ApiAuthException(trans('errors.api_user_token_expired'), 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$token->user->can('access-api')) {
|
if (!$token->user->can(Permission::AccessApi)) {
|
||||||
throw new ApiAuthException(trans('errors.api_user_no_api_permission'), 403);
|
throw new ApiAuthException(trans('errors.api_user_no_api_permission'), 403);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Api;
|
|||||||
|
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@@ -16,8 +17,8 @@ class UserApiTokenController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request, int $userId)
|
public function create(Request $request, int $userId)
|
||||||
{
|
{
|
||||||
$this->checkPermission('access-api');
|
$this->checkPermission(Permission::AccessApi);
|
||||||
$this->checkPermissionOrCurrentUser('users-manage', $userId);
|
$this->checkPermissionOrCurrentUser(Permission::UsersManage, $userId);
|
||||||
$this->updateContext($request);
|
$this->updateContext($request);
|
||||||
|
|
||||||
$user = User::query()->findOrFail($userId);
|
$user = User::query()->findOrFail($userId);
|
||||||
@@ -35,8 +36,8 @@ class UserApiTokenController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request, int $userId)
|
public function store(Request $request, int $userId)
|
||||||
{
|
{
|
||||||
$this->checkPermission('access-api');
|
$this->checkPermission(Permission::AccessApi);
|
||||||
$this->checkPermissionOrCurrentUser('users-manage', $userId);
|
$this->checkPermissionOrCurrentUser(Permission::UsersManage, $userId);
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'name' => ['required', 'max:250'],
|
'name' => ['required', 'max:250'],
|
||||||
@@ -143,8 +144,8 @@ class UserApiTokenController extends Controller
|
|||||||
*/
|
*/
|
||||||
protected function checkPermissionAndFetchUserToken(int $userId, int $tokenId): array
|
protected function checkPermissionAndFetchUserToken(int $userId, int $tokenId): array
|
||||||
{
|
{
|
||||||
$this->checkPermissionOr('users-manage', function () use ($userId) {
|
$this->checkPermissionOr(Permission::UsersManage, function () use ($userId) {
|
||||||
return $userId === user()->id && userCan('access-api');
|
return $userId === user()->id && userCan(Permission::AccessApi);
|
||||||
});
|
});
|
||||||
|
|
||||||
$user = User::query()->findOrFail($userId);
|
$user = User::query()->findOrFail($userId);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
use BookStack\App\AppVersion;
|
use BookStack\App\AppVersion;
|
||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\Facades\Theme;
|
use BookStack\Facades\Theme;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Permissions\PermissionApplicator;
|
use BookStack\Permissions\PermissionApplicator;
|
||||||
use BookStack\Settings\SettingService;
|
use BookStack\Settings\SettingService;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
@@ -39,7 +40,7 @@ function user(): User
|
|||||||
* Check if the current user has a permission. If an ownable element
|
* Check if the current user has a permission. If an ownable element
|
||||||
* is passed in the jointPermissions are checked against that particular item.
|
* is passed in the jointPermissions are checked against that particular item.
|
||||||
*/
|
*/
|
||||||
function userCan(string $permission, ?Model $ownable = null): bool
|
function userCan(string|Permission $permission, ?Model $ownable = null): bool
|
||||||
{
|
{
|
||||||
if (is_null($ownable)) {
|
if (is_null($ownable)) {
|
||||||
return user()->can($permission);
|
return user()->can($permission);
|
||||||
@@ -55,7 +56,7 @@ function userCan(string $permission, ?Model $ownable = null): bool
|
|||||||
* Check if the current user can perform the given action on any items in the system.
|
* Check if the current user can perform the given action on any items in the system.
|
||||||
* Can be provided the class name of an entity to filter ability to that specific entity type.
|
* Can be provided the class name of an entity to filter ability to that specific entity type.
|
||||||
*/
|
*/
|
||||||
function userCanOnAny(string $action, string $entityClass = ''): bool
|
function userCanOnAny(string|Permission $action, string $entityClass = ''): bool
|
||||||
{
|
{
|
||||||
$permissions = app()->make(PermissionApplicator::class);
|
$permissions = app()->make(PermissionApplicator::class);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use BookStack\Entities\Queries\PageQueries;
|
|||||||
use BookStack\Entities\Repos\BookRepo;
|
use BookStack\Entities\Repos\BookRepo;
|
||||||
use BookStack\Entities\Tools\BookContents;
|
use BookStack\Entities\Tools\BookContents;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ class BookApiController extends ApiController
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
$requestData = $this->validate($request, $this->rules()['create']);
|
$requestData = $this->validate($request, $this->rules()['create']);
|
||||||
|
|
||||||
$book = $this->bookRepo->create($requestData);
|
$book = $this->bookRepo->create($requestData);
|
||||||
@@ -92,7 +93,7 @@ class BookApiController extends ApiController
|
|||||||
public function update(Request $request, string $id)
|
public function update(Request $request, string $id)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleByIdOrFail(intval($id));
|
$book = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
|
|
||||||
$requestData = $this->validate($request, $this->rules()['update']);
|
$requestData = $this->validate($request, $this->rules()['update']);
|
||||||
$book = $this->bookRepo->update($book, $requestData);
|
$book = $this->bookRepo->update($book, $requestData);
|
||||||
@@ -109,7 +110,7 @@ class BookApiController extends ApiController
|
|||||||
public function delete(string $id)
|
public function delete(string $id)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleByIdOrFail(intval($id));
|
$book = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('book-delete', $book);
|
$this->checkOwnablePermission(Permission::BookDelete, $book);
|
||||||
|
|
||||||
$this->bookRepo->destroy($book);
|
$this->bookRepo->destroy($book);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use BookStack\Exceptions\ImageUploadException;
|
|||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceFetcher;
|
use BookStack\References\ReferenceFetcher;
|
||||||
use BookStack\Util\DatabaseTransaction;
|
use BookStack\Util\DatabaseTransaction;
|
||||||
use BookStack\Util\SimpleListOptions;
|
use BookStack\Util\SimpleListOptions;
|
||||||
@@ -73,12 +74,12 @@ class BookController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(?string $shelfSlug = null)
|
public function create(?string $shelfSlug = null)
|
||||||
{
|
{
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
|
|
||||||
$bookshelf = null;
|
$bookshelf = null;
|
||||||
if ($shelfSlug !== null) {
|
if ($shelfSlug !== null) {
|
||||||
$bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
|
$bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
|
||||||
$this->checkOwnablePermission('bookshelf-update', $bookshelf);
|
$this->checkOwnablePermission(Permission::BookshelfUpdate, $bookshelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.books_create'));
|
$this->setPageTitle(trans('entities.books_create'));
|
||||||
@@ -96,7 +97,7 @@ class BookController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request, ?string $shelfSlug = null)
|
public function store(Request $request, ?string $shelfSlug = null)
|
||||||
{
|
{
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'description_html' => ['string', 'max:2000'],
|
'description_html' => ['string', 'max:2000'],
|
||||||
@@ -108,7 +109,7 @@ class BookController extends Controller
|
|||||||
$bookshelf = null;
|
$bookshelf = null;
|
||||||
if ($shelfSlug !== null) {
|
if ($shelfSlug !== null) {
|
||||||
$bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
|
$bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
|
||||||
$this->checkOwnablePermission('bookshelf-update', $bookshelf);
|
$this->checkOwnablePermission(Permission::BookshelfUpdate, $bookshelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
$book = $this->bookRepo->create($validated);
|
$book = $this->bookRepo->create($validated);
|
||||||
@@ -154,7 +155,7 @@ class BookController extends Controller
|
|||||||
public function edit(string $slug)
|
public function edit(string $slug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($slug);
|
$book = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
$this->setPageTitle(trans('entities.books_edit_named', ['bookName' => $book->getShortName()]));
|
$this->setPageTitle(trans('entities.books_edit_named', ['bookName' => $book->getShortName()]));
|
||||||
|
|
||||||
return view('books.edit', ['book' => $book, 'current' => $book]);
|
return view('books.edit', ['book' => $book, 'current' => $book]);
|
||||||
@@ -170,7 +171,7 @@ class BookController extends Controller
|
|||||||
public function update(Request $request, string $slug)
|
public function update(Request $request, string $slug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($slug);
|
$book = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
|
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
@@ -197,7 +198,7 @@ class BookController extends Controller
|
|||||||
public function showDelete(string $bookSlug)
|
public function showDelete(string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-delete', $book);
|
$this->checkOwnablePermission(Permission::BookDelete, $book);
|
||||||
$this->setPageTitle(trans('entities.books_delete_named', ['bookName' => $book->getShortName()]));
|
$this->setPageTitle(trans('entities.books_delete_named', ['bookName' => $book->getShortName()]));
|
||||||
|
|
||||||
return view('books.delete', ['book' => $book, 'current' => $book]);
|
return view('books.delete', ['book' => $book, 'current' => $book]);
|
||||||
@@ -211,7 +212,7 @@ class BookController extends Controller
|
|||||||
public function destroy(string $bookSlug)
|
public function destroy(string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-delete', $book);
|
$this->checkOwnablePermission(Permission::BookDelete, $book);
|
||||||
|
|
||||||
$this->bookRepo->destroy($book);
|
$this->bookRepo->destroy($book);
|
||||||
|
|
||||||
@@ -226,7 +227,7 @@ class BookController extends Controller
|
|||||||
public function showCopy(string $bookSlug)
|
public function showCopy(string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-view', $book);
|
$this->checkOwnablePermission(Permission::BookView, $book);
|
||||||
|
|
||||||
session()->flashInput(['name' => $book->name]);
|
session()->flashInput(['name' => $book->name]);
|
||||||
|
|
||||||
@@ -243,8 +244,8 @@ class BookController extends Controller
|
|||||||
public function copy(Request $request, Cloner $cloner, string $bookSlug)
|
public function copy(Request $request, Cloner $cloner, string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-view', $book);
|
$this->checkOwnablePermission(Permission::BookView, $book);
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
|
|
||||||
$newName = $request->get('name') ?: $book->name;
|
$newName = $request->get('name') ?: $book->name;
|
||||||
$bookCopy = $cloner->cloneBook($book, $newName);
|
$bookCopy = $cloner->cloneBook($book, $newName);
|
||||||
@@ -259,10 +260,10 @@ class BookController extends Controller
|
|||||||
public function convertToShelf(HierarchyTransformer $transformer, string $bookSlug)
|
public function convertToShelf(HierarchyTransformer $transformer, string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
$this->checkOwnablePermission('book-delete', $book);
|
$this->checkOwnablePermission(Permission::BookDelete, $book);
|
||||||
$this->checkPermission('bookshelf-create-all');
|
$this->checkPermission(Permission::BookshelfCreateAll);
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
|
|
||||||
$shelf = (new DatabaseTransaction(function () use ($book, $transformer) {
|
$shelf = (new DatabaseTransaction(function () use ($book, $transformer) {
|
||||||
return $transformer->transformBookToShelf($book);
|
return $transformer->transformBookToShelf($book);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Entities\Models\Bookshelf;
|
|||||||
use BookStack\Entities\Queries\BookshelfQueries;
|
use BookStack\Entities\Queries\BookshelfQueries;
|
||||||
use BookStack\Entities\Repos\BookshelfRepo;
|
use BookStack\Entities\Repos\BookshelfRepo;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -45,7 +46,7 @@ class BookshelfApiController extends ApiController
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('bookshelf-create-all');
|
$this->checkPermission(Permission::BookshelfCreateAll);
|
||||||
$requestData = $this->validate($request, $this->rules()['create']);
|
$requestData = $this->validate($request, $this->rules()['create']);
|
||||||
|
|
||||||
$bookIds = $request->get('books', []);
|
$bookIds = $request->get('books', []);
|
||||||
@@ -84,7 +85,7 @@ class BookshelfApiController extends ApiController
|
|||||||
public function update(Request $request, string $id)
|
public function update(Request $request, string $id)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleByIdOrFail(intval($id));
|
$shelf = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('bookshelf-update', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
|
||||||
|
|
||||||
$requestData = $this->validate($request, $this->rules()['update']);
|
$requestData = $this->validate($request, $this->rules()['update']);
|
||||||
$bookIds = $request->get('books', null);
|
$bookIds = $request->get('books', null);
|
||||||
@@ -103,7 +104,7 @@ class BookshelfApiController extends ApiController
|
|||||||
public function delete(string $id)
|
public function delete(string $id)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleByIdOrFail(intval($id));
|
$shelf = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('bookshelf-delete', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
|
||||||
|
|
||||||
$this->bookshelfRepo->destroy($shelf);
|
$this->bookshelfRepo->destroy($shelf);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use BookStack\Entities\Tools\ShelfContext;
|
|||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceFetcher;
|
use BookStack\References\ReferenceFetcher;
|
||||||
use BookStack\Util\SimpleListOptions;
|
use BookStack\Util\SimpleListOptions;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -68,7 +69,7 @@ class BookshelfController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
$this->checkPermission('bookshelf-create-all');
|
$this->checkPermission(Permission::BookshelfCreateAll);
|
||||||
$books = $this->bookQueries->visibleForList()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
|
$books = $this->bookQueries->visibleForList()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
|
||||||
$this->setPageTitle(trans('entities.shelves_create'));
|
$this->setPageTitle(trans('entities.shelves_create'));
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ class BookshelfController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('bookshelf-create-all');
|
$this->checkPermission(Permission::BookshelfCreateAll);
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'description_html' => ['string', 'max:2000'],
|
'description_html' => ['string', 'max:2000'],
|
||||||
@@ -105,7 +106,7 @@ class BookshelfController extends Controller
|
|||||||
public function show(Request $request, ActivityQueries $activities, string $slug)
|
public function show(Request $request, ActivityQueries $activities, string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('bookshelf-view', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfView, $shelf);
|
||||||
|
|
||||||
$listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([
|
$listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([
|
||||||
'default' => trans('common.sort_default'),
|
'default' => trans('common.sort_default'),
|
||||||
@@ -143,7 +144,7 @@ class BookshelfController extends Controller
|
|||||||
public function edit(string $slug)
|
public function edit(string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('bookshelf-update', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
|
||||||
|
|
||||||
$shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
|
$shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
|
||||||
$books = $this->bookQueries->visibleForList()
|
$books = $this->bookQueries->visibleForList()
|
||||||
@@ -169,7 +170,7 @@ class BookshelfController extends Controller
|
|||||||
public function update(Request $request, string $slug)
|
public function update(Request $request, string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('bookshelf-update', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'description_html' => ['string', 'max:2000'],
|
'description_html' => ['string', 'max:2000'],
|
||||||
@@ -195,7 +196,7 @@ class BookshelfController extends Controller
|
|||||||
public function showDelete(string $slug)
|
public function showDelete(string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('bookshelf-delete', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()]));
|
$this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()]));
|
||||||
|
|
||||||
@@ -210,7 +211,7 @@ class BookshelfController extends Controller
|
|||||||
public function destroy(string $slug)
|
public function destroy(string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('bookshelf-delete', $shelf);
|
$this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
|
||||||
|
|
||||||
$this->shelfRepo->destroy($shelf);
|
$this->shelfRepo->destroy($shelf);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use BookStack\Entities\Queries\EntityQueries;
|
|||||||
use BookStack\Entities\Repos\ChapterRepo;
|
use BookStack\Entities\Repos\ChapterRepo;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ class ChapterApiController extends ApiController
|
|||||||
|
|
||||||
$bookId = $request->get('book_id');
|
$bookId = $request->get('book_id');
|
||||||
$book = $this->entityQueries->books->findVisibleByIdOrFail(intval($bookId));
|
$book = $this->entityQueries->books->findVisibleByIdOrFail(intval($bookId));
|
||||||
$this->checkOwnablePermission('chapter-create', $book);
|
$this->checkOwnablePermission(Permission::ChapterCreate, $book);
|
||||||
|
|
||||||
$chapter = $this->chapterRepo->create($requestData, $book);
|
$chapter = $this->chapterRepo->create($requestData, $book);
|
||||||
|
|
||||||
@@ -101,10 +102,10 @@ class ChapterApiController extends ApiController
|
|||||||
{
|
{
|
||||||
$requestData = $this->validate($request, $this->rules()['update']);
|
$requestData = $this->validate($request, $this->rules()['update']);
|
||||||
$chapter = $this->queries->findVisibleByIdOrFail(intval($id));
|
$chapter = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
|
|
||||||
if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) {
|
if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) {
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->chapterRepo->move($chapter, "book:{$requestData['book_id']}");
|
$this->chapterRepo->move($chapter, "book:{$requestData['book_id']}");
|
||||||
@@ -129,7 +130,7 @@ class ChapterApiController extends ApiController
|
|||||||
public function delete(string $id)
|
public function delete(string $id)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleByIdOrFail(intval($id));
|
$chapter = $this->queries->findVisibleByIdOrFail(intval($id));
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
$this->chapterRepo->destroy($chapter);
|
$this->chapterRepo->destroy($chapter);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use BookStack\Exceptions\NotFoundException;
|
|||||||
use BookStack\Exceptions\NotifyException;
|
use BookStack\Exceptions\NotifyException;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceFetcher;
|
use BookStack\References\ReferenceFetcher;
|
||||||
use BookStack\Util\DatabaseTransaction;
|
use BookStack\Util\DatabaseTransaction;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -39,7 +40,7 @@ class ChapterController extends Controller
|
|||||||
public function create(string $bookSlug)
|
public function create(string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('chapter-create', $book);
|
$this->checkOwnablePermission(Permission::ChapterCreate, $book);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.chapters_create'));
|
$this->setPageTitle(trans('entities.chapters_create'));
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ class ChapterController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$book = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('chapter-create', $book);
|
$this->checkOwnablePermission(Permission::ChapterCreate, $book);
|
||||||
|
|
||||||
$chapter = $this->chapterRepo->create($validated, $book);
|
$chapter = $this->chapterRepo->create($validated, $book);
|
||||||
|
|
||||||
@@ -77,7 +78,6 @@ class ChapterController extends Controller
|
|||||||
public function show(string $bookSlug, string $chapterSlug)
|
public function show(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-view', $chapter);
|
|
||||||
|
|
||||||
$sidebarTree = (new BookContents($chapter->book))->getTree();
|
$sidebarTree = (new BookContents($chapter->book))->getTree();
|
||||||
$pages = $this->entityQueries->pages->visibleForChapterList($chapter->id)->get();
|
$pages = $this->entityQueries->pages->visibleForChapterList($chapter->id)->get();
|
||||||
@@ -106,7 +106,7 @@ class ChapterController extends Controller
|
|||||||
public function edit(string $bookSlug, string $chapterSlug)
|
public function edit(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
|
$this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ class ChapterController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
|
|
||||||
$this->chapterRepo->update($chapter, $validated);
|
$this->chapterRepo->update($chapter, $validated);
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ class ChapterController extends Controller
|
|||||||
public function showDelete(string $bookSlug, string $chapterSlug)
|
public function showDelete(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
|
$this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ class ChapterController extends Controller
|
|||||||
public function destroy(string $bookSlug, string $chapterSlug)
|
public function destroy(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
$this->chapterRepo->destroy($chapter);
|
$this->chapterRepo->destroy($chapter);
|
||||||
|
|
||||||
@@ -175,8 +175,8 @@ class ChapterController extends Controller
|
|||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
|
$this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
return view('chapters.move', [
|
return view('chapters.move', [
|
||||||
'chapter' => $chapter,
|
'chapter' => $chapter,
|
||||||
@@ -192,8 +192,8 @@ class ChapterController extends Controller
|
|||||||
public function move(Request $request, string $bookSlug, string $chapterSlug)
|
public function move(Request $request, string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection', null);
|
$entitySelection = $request->get('entity_selection', null);
|
||||||
if ($entitySelection === null || $entitySelection === '') {
|
if ($entitySelection === null || $entitySelection === '') {
|
||||||
@@ -221,7 +221,6 @@ class ChapterController extends Controller
|
|||||||
public function showCopy(string $bookSlug, string $chapterSlug)
|
public function showCopy(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-view', $chapter);
|
|
||||||
|
|
||||||
session()->flashInput(['name' => $chapter->name]);
|
session()->flashInput(['name' => $chapter->name]);
|
||||||
|
|
||||||
@@ -240,7 +239,6 @@ class ChapterController extends Controller
|
|||||||
public function copy(Request $request, Cloner $cloner, string $bookSlug, string $chapterSlug)
|
public function copy(Request $request, Cloner $cloner, string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-view', $chapter);
|
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection') ?: null;
|
$entitySelection = $request->get('entity_selection') ?: null;
|
||||||
$newParentBook = $entitySelection ? $this->entityQueries->findVisibleByStringIdentifier($entitySelection) : $chapter->getParent();
|
$newParentBook = $entitySelection ? $this->entityQueries->findVisibleByStringIdentifier($entitySelection) : $chapter->getParent();
|
||||||
@@ -251,7 +249,7 @@ class ChapterController extends Controller
|
|||||||
return redirect($chapter->getUrl('/copy'));
|
return redirect($chapter->getUrl('/copy'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('chapter-create', $newParentBook);
|
$this->checkOwnablePermission(Permission::ChapterCreate, $newParentBook);
|
||||||
|
|
||||||
$newName = $request->get('name') ?: $chapter->name;
|
$newName = $request->get('name') ?: $chapter->name;
|
||||||
$chapterCopy = $cloner->cloneChapter($chapter, $newParentBook, $newName);
|
$chapterCopy = $cloner->cloneChapter($chapter, $newParentBook, $newName);
|
||||||
@@ -266,9 +264,9 @@ class ChapterController extends Controller
|
|||||||
public function convertToBook(HierarchyTransformer $transformer, string $bookSlug, string $chapterSlug)
|
public function convertToBook(HierarchyTransformer $transformer, string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterUpdate, $chapter);
|
||||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
$this->checkOwnablePermission(Permission::ChapterDelete, $chapter);
|
||||||
$this->checkPermission('book-create-all');
|
$this->checkPermission(Permission::BookCreateAll);
|
||||||
|
|
||||||
$book = (new DatabaseTransaction(function () use ($chapter, $transformer) {
|
$book = (new DatabaseTransaction(function () use ($chapter, $transformer) {
|
||||||
return $transformer->transformChapterToBook($chapter);
|
return $transformer->transformChapterToBook($chapter);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Entities\Queries\PageQueries;
|
|||||||
use BookStack\Entities\Repos\PageRepo;
|
use BookStack\Entities\Repos\PageRepo;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ class PageApiController extends ApiController
|
|||||||
} else {
|
} else {
|
||||||
$parent = $this->entityQueries->books->findVisibleByIdOrFail(intval($request->get('book_id')));
|
$parent = $this->entityQueries->books->findVisibleByIdOrFail(intval($request->get('book_id')));
|
||||||
}
|
}
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission(Permission::PageCreate, $parent);
|
||||||
|
|
||||||
$draft = $this->pageRepo->getNewDraftPage($parent);
|
$draft = $this->pageRepo->getNewDraftPage($parent);
|
||||||
$this->pageRepo->publishDraft($draft, $request->only(array_keys($this->rules['create'])));
|
$this->pageRepo->publishDraft($draft, $request->only(array_keys($this->rules['create'])));
|
||||||
@@ -116,7 +117,7 @@ class PageApiController extends ApiController
|
|||||||
$requestData = $this->validate($request, $this->rules['update']);
|
$requestData = $this->validate($request, $this->rules['update']);
|
||||||
|
|
||||||
$page = $this->queries->findVisibleByIdOrFail($id);
|
$page = $this->queries->findVisibleByIdOrFail($id);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$parent = null;
|
$parent = null;
|
||||||
if ($request->has('chapter_id')) {
|
if ($request->has('chapter_id')) {
|
||||||
@@ -126,7 +127,7 @@ class PageApiController extends ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($parent && !$parent->matches($page->getParent())) {
|
if ($parent && !$parent->matches($page->getParent())) {
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->pageRepo->move($page, $parent->getType() . ':' . $parent->id);
|
$this->pageRepo->move($page, $parent->getType() . ':' . $parent->id);
|
||||||
@@ -151,7 +152,7 @@ class PageApiController extends ApiController
|
|||||||
public function delete(string $id)
|
public function delete(string $id)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleByIdOrFail($id);
|
$page = $this->queries->findVisibleByIdOrFail($id);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
|
|
||||||
$this->pageRepo->destroy($page);
|
$this->pageRepo->destroy($page);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use BookStack\Exceptions\NotFoundException;
|
|||||||
use BookStack\Exceptions\NotifyException;
|
use BookStack\Exceptions\NotifyException;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceFetcher;
|
use BookStack\References\ReferenceFetcher;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
@@ -50,7 +51,7 @@ class PageController extends Controller
|
|||||||
$parent = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
$parent = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission(Permission::PageCreate, $parent);
|
||||||
|
|
||||||
// Redirect to draft edit screen if signed in
|
// Redirect to draft edit screen if signed in
|
||||||
if ($this->isSignedIn()) {
|
if ($this->isSignedIn()) {
|
||||||
@@ -82,7 +83,7 @@ class PageController extends Controller
|
|||||||
$parent = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
$parent = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission(Permission::PageCreate, $parent);
|
||||||
|
|
||||||
$page = $this->pageRepo->getNewDraftPage($parent);
|
$page = $this->pageRepo->getNewDraftPage($parent);
|
||||||
$this->pageRepo->publishDraft($page, [
|
$this->pageRepo->publishDraft($page, [
|
||||||
@@ -100,7 +101,7 @@ class PageController extends Controller
|
|||||||
public function editDraft(Request $request, string $bookSlug, int $pageId)
|
public function editDraft(Request $request, string $bookSlug, int $pageId)
|
||||||
{
|
{
|
||||||
$draft = $this->queries->findVisibleByIdOrFail($pageId);
|
$draft = $this->queries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-create', $draft->getParent());
|
$this->checkOwnablePermission(Permission::PageCreate, $draft->getParent());
|
||||||
|
|
||||||
$editorData = new PageEditorData($draft, $this->entityQueries, $request->query('editor', ''));
|
$editorData = new PageEditorData($draft, $this->entityQueries, $request->query('editor', ''));
|
||||||
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
||||||
@@ -120,7 +121,7 @@ class PageController extends Controller
|
|||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
]);
|
]);
|
||||||
$draftPage = $this->queries->findVisibleByIdOrFail($pageId);
|
$draftPage = $this->queries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-create', $draftPage->getParent());
|
$this->checkOwnablePermission(Permission::PageCreate, $draftPage->getParent());
|
||||||
|
|
||||||
$page = $this->pageRepo->publishDraft($draftPage, $request->all());
|
$page = $this->pageRepo->publishDraft($draftPage, $request->all());
|
||||||
|
|
||||||
@@ -148,8 +149,6 @@ class PageController extends Controller
|
|||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
|
||||||
|
|
||||||
$pageContent = (new PageContent($page));
|
$pageContent = (new PageContent($page));
|
||||||
$page->html = $pageContent->render();
|
$page->html = $pageContent->render();
|
||||||
$pageNav = $pageContent->getNavigation($page->html);
|
$pageNav = $pageContent->getNavigation($page->html);
|
||||||
@@ -197,7 +196,7 @@ class PageController extends Controller
|
|||||||
public function edit(Request $request, string $bookSlug, string $pageSlug)
|
public function edit(Request $request, string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page, $page->getUrl());
|
$this->checkOwnablePermission(Permission::PageUpdate, $page, $page->getUrl());
|
||||||
|
|
||||||
$editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', ''));
|
$editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', ''));
|
||||||
if ($editorData->getWarnings()) {
|
if ($editorData->getWarnings()) {
|
||||||
@@ -221,7 +220,7 @@ class PageController extends Controller
|
|||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
]);
|
]);
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$this->pageRepo->update($page, $request->all());
|
$this->pageRepo->update($page, $request->all());
|
||||||
|
|
||||||
@@ -236,7 +235,7 @@ class PageController extends Controller
|
|||||||
public function saveDraft(Request $request, int $pageId)
|
public function saveDraft(Request $request, int $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
if (!$this->isSignedIn()) {
|
if (!$this->isSignedIn()) {
|
||||||
return $this->jsonError(trans('errors.guests_cannot_save_drafts'), 500);
|
return $this->jsonError(trans('errors.guests_cannot_save_drafts'), 500);
|
||||||
@@ -273,7 +272,7 @@ class PageController extends Controller
|
|||||||
public function showDelete(string $bookSlug, string $pageSlug)
|
public function showDelete(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
$this->setPageTitle(trans('entities.pages_delete_named', ['pageName' => $page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_delete_named', ['pageName' => $page->getShortName()]));
|
||||||
$usedAsTemplate =
|
$usedAsTemplate =
|
||||||
$this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
|
$this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
|
||||||
@@ -295,7 +294,7 @@ class PageController extends Controller
|
|||||||
public function showDeleteDraft(string $bookSlug, int $pageId)
|
public function showDeleteDraft(string $bookSlug, int $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()]));
|
||||||
$usedAsTemplate =
|
$usedAsTemplate =
|
||||||
$this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
|
$this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
|
||||||
@@ -318,7 +317,7 @@ class PageController extends Controller
|
|||||||
public function destroy(string $bookSlug, string $pageSlug)
|
public function destroy(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
$parent = $page->getParent();
|
$parent = $page->getParent();
|
||||||
|
|
||||||
$this->pageRepo->destroy($page);
|
$this->pageRepo->destroy($page);
|
||||||
@@ -337,13 +336,13 @@ class PageController extends Controller
|
|||||||
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
$page = $this->queries->findVisibleByIdOrFail($pageId);
|
||||||
$book = $page->book;
|
$book = $page->book;
|
||||||
$chapter = $page->chapter;
|
$chapter = $page->chapter;
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$this->pageRepo->destroy($page);
|
$this->pageRepo->destroy($page);
|
||||||
|
|
||||||
$this->showSuccessNotification(trans('entities.pages_delete_draft_success'));
|
$this->showSuccessNotification(trans('entities.pages_delete_draft_success'));
|
||||||
|
|
||||||
if ($chapter && userCan('view', $chapter)) {
|
if ($chapter && userCan(Permission::ChapterView, $chapter)) {
|
||||||
return redirect($chapter->getUrl());
|
return redirect($chapter->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,8 +383,8 @@ class PageController extends Controller
|
|||||||
public function showMove(string $bookSlug, string $pageSlug)
|
public function showMove(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
|
|
||||||
return view('pages.move', [
|
return view('pages.move', [
|
||||||
'book' => $page->book,
|
'book' => $page->book,
|
||||||
@@ -402,8 +401,8 @@ class PageController extends Controller
|
|||||||
public function move(Request $request, string $bookSlug, string $pageSlug)
|
public function move(Request $request, string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection', null);
|
$entitySelection = $request->get('entity_selection', null);
|
||||||
if ($entitySelection === null || $entitySelection === '') {
|
if ($entitySelection === null || $entitySelection === '') {
|
||||||
@@ -431,7 +430,6 @@ class PageController extends Controller
|
|||||||
public function showCopy(string $bookSlug, string $pageSlug)
|
public function showCopy(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
|
||||||
session()->flashInput(['name' => $page->name]);
|
session()->flashInput(['name' => $page->name]);
|
||||||
|
|
||||||
return view('pages.copy', [
|
return view('pages.copy', [
|
||||||
@@ -449,7 +447,7 @@ class PageController extends Controller
|
|||||||
public function copy(Request $request, Cloner $cloner, string $bookSlug, string $pageSlug)
|
public function copy(Request $request, Cloner $cloner, string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
$this->checkOwnablePermission(Permission::PageView, $page);
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection') ?: null;
|
$entitySelection = $request->get('entity_selection') ?: null;
|
||||||
$newParent = $entitySelection ? $this->entityQueries->findVisibleByStringIdentifier($entitySelection) : $page->getParent();
|
$newParent = $entitySelection ? $this->entityQueries->findVisibleByStringIdentifier($entitySelection) : $page->getParent();
|
||||||
@@ -460,7 +458,7 @@ class PageController extends Controller
|
|||||||
return redirect($page->getUrl('/copy'));
|
return redirect($page->getUrl('/copy'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-create', $newParent);
|
$this->checkOwnablePermission(Permission::PageCreate, $newParent);
|
||||||
|
|
||||||
$newName = $request->get('name') ?: $page->name;
|
$newName = $request->get('name') ?: $page->name;
|
||||||
$pageCopy = $cloner->clonePage($page, $newParent, $newName);
|
$pageCopy = $cloner->clonePage($page, $newParent, $newName);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use BookStack\Entities\Tools\PageContent;
|
|||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Util\SimpleListOptions;
|
use BookStack\Util\SimpleListOptions;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Ssddanbrown\HtmlDiff\Diff;
|
use Ssddanbrown\HtmlDiff\Diff;
|
||||||
@@ -124,7 +125,7 @@ class PageRevisionController extends Controller
|
|||||||
public function restore(string $bookSlug, string $pageSlug, int $revisionId)
|
public function restore(string $bookSlug, string $pageSlug, int $revisionId)
|
||||||
{
|
{
|
||||||
$page = $this->pageQueries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->pageQueries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$page = $this->pageRepo->restoreRevision($page, $revisionId);
|
$page = $this->pageRepo->restoreRevision($page, $revisionId);
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ class PageRevisionController extends Controller
|
|||||||
public function destroy(string $bookSlug, string $pageSlug, int $revId)
|
public function destroy(string $bookSlug, string $pageSlug, int $revId)
|
||||||
{
|
{
|
||||||
$page = $this->pageQueries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->pageQueries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission(Permission::PageDelete, $page);
|
||||||
|
|
||||||
$revision = $page->revisions()->where('id', '=', $revId)->first();
|
$revision = $page->revisions()->where('id', '=', $revId)->first();
|
||||||
if ($revision === null) {
|
if ($revision === null) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use BookStack\Entities\Models\Deletion;
|
|||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use BookStack\Entities\Repos\DeletionRepo;
|
use BookStack\Entities\Repos\DeletionRepo;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
@@ -17,8 +18,8 @@ class RecycleBinApiController extends ApiController
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware(function ($request, $next) {
|
$this->middleware(function ($request, $next) {
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->checkPermission('restrictions-manage-all');
|
$this->checkPermission(Permission::RestrictionsManageAll);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Entities\Models\Entity;
|
|||||||
use BookStack\Entities\Repos\DeletionRepo;
|
use BookStack\Entities\Repos\DeletionRepo;
|
||||||
use BookStack\Entities\Tools\TrashCan;
|
use BookStack\Entities\Tools\TrashCan;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class RecycleBinController extends Controller
|
class RecycleBinController extends Controller
|
||||||
{
|
{
|
||||||
@@ -20,8 +21,8 @@ class RecycleBinController extends Controller
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware(function ($request, $next) {
|
$this->middleware(function ($request, $next) {
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->checkPermission('restrictions-manage-all');
|
$this->checkPermission(Permission::RestrictionsManageAll);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use BookStack\Entities\Tools\TrashCan;
|
|||||||
use BookStack\Exceptions\MoveOperationException;
|
use BookStack\Exceptions\MoveOperationException;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Util\DatabaseTransaction;
|
use BookStack\Util\DatabaseTransaction;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ class ChapterRepo
|
|||||||
throw new MoveOperationException('Book to move chapter into not found');
|
throw new MoveOperationException('Book to move chapter into not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userCan('chapter-create', $parent)) {
|
if (!userCan(Permission::ChapterCreate, $parent)) {
|
||||||
throw new PermissionsException('User does not have permission to create a chapter within the chosen book');
|
throw new PermissionsException('User does not have permission to create a chapter within the chosen book');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use BookStack\Entities\Tools\TrashCan;
|
|||||||
use BookStack\Exceptions\MoveOperationException;
|
use BookStack\Exceptions\MoveOperationException;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceStore;
|
use BookStack\References\ReferenceStore;
|
||||||
use BookStack\References\ReferenceUpdater;
|
use BookStack\References\ReferenceUpdater;
|
||||||
use BookStack\Util\DatabaseTransaction;
|
use BookStack\Util\DatabaseTransaction;
|
||||||
@@ -55,7 +56,7 @@ class PageRepo
|
|||||||
}
|
}
|
||||||
|
|
||||||
$defaultTemplate = $page->chapter->defaultTemplate ?? $page->book->defaultTemplate;
|
$defaultTemplate = $page->chapter->defaultTemplate ?? $page->book->defaultTemplate;
|
||||||
if ($defaultTemplate && userCan('view', $defaultTemplate)) {
|
if ($defaultTemplate && userCan(Permission::PageView, $defaultTemplate)) {
|
||||||
$page->forceFill([
|
$page->forceFill([
|
||||||
'html' => $defaultTemplate->html,
|
'html' => $defaultTemplate->html,
|
||||||
'markdown' => $defaultTemplate->markdown,
|
'markdown' => $defaultTemplate->markdown,
|
||||||
@@ -142,7 +143,7 @@ class PageRepo
|
|||||||
|
|
||||||
protected function updateTemplateStatusAndContentFromInput(Page $page, array $input): void
|
protected function updateTemplateStatusAndContentFromInput(Page $page, array $input): void
|
||||||
{
|
{
|
||||||
if (isset($input['template']) && userCan('templates-manage')) {
|
if (isset($input['template']) && userCan(Permission::TemplatesManage)) {
|
||||||
$page->template = ($input['template'] === 'true');
|
$page->template = ($input['template'] === 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +166,7 @@ class PageRepo
|
|||||||
$pageContent->setNewHTML($input['html'], user());
|
$pageContent->setNewHTML($input['html'], user());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($newEditor !== $currentEditor || empty($page->editor)) && userCan('editor-change')) {
|
if (($newEditor !== $currentEditor || empty($page->editor)) && userCan(Permission::EditorChange)) {
|
||||||
$page->editor = $newEditor->value;
|
$page->editor = $newEditor->value;
|
||||||
} elseif (empty($page->editor)) {
|
} elseif (empty($page->editor)) {
|
||||||
$page->editor = $defaultEditor->value;
|
$page->editor = $defaultEditor->value;
|
||||||
@@ -271,7 +272,7 @@ class PageRepo
|
|||||||
throw new MoveOperationException('Book or chapter to move page into not found');
|
throw new MoveOperationException('Book or chapter to move page into not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userCan('page-create', $parent)) {
|
if (!userCan(Permission::PageCreate, $parent)) {
|
||||||
throw new PermissionsException('User does not have permission to create a page within the new parent');
|
throw new PermissionsException('User does not have permission to create a page within the new parent');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use BookStack\Entities\Models\Page;
|
|||||||
use BookStack\Entities\Repos\BookRepo;
|
use BookStack\Entities\Repos\BookRepo;
|
||||||
use BookStack\Entities\Repos\ChapterRepo;
|
use BookStack\Entities\Repos\ChapterRepo;
|
||||||
use BookStack\Entities\Repos\PageRepo;
|
use BookStack\Entities\Repos\PageRepo;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Image;
|
use BookStack\Uploads\Image;
|
||||||
use BookStack\Uploads\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
@@ -49,7 +50,7 @@ class Cloner
|
|||||||
|
|
||||||
$copyChapter = $this->chapterRepo->create($chapterDetails, $parent);
|
$copyChapter = $this->chapterRepo->create($chapterDetails, $parent);
|
||||||
|
|
||||||
if (userCan('page-create', $copyChapter)) {
|
if (userCan(Permission::PageCreate, $copyChapter)) {
|
||||||
/** @var Page $page */
|
/** @var Page $page */
|
||||||
foreach ($original->getVisiblePages() as $page) {
|
foreach ($original->getVisiblePages() as $page) {
|
||||||
$this->clonePage($page, $copyChapter, $page->name);
|
$this->clonePage($page, $copyChapter, $page->name);
|
||||||
@@ -61,7 +62,7 @@ class Cloner
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone the given book.
|
* Clone the given book.
|
||||||
* Clones all child chapters & pages.
|
* Clones all child chapters and pages.
|
||||||
*/
|
*/
|
||||||
public function cloneBook(Book $original, string $newName): Book
|
public function cloneBook(Book $original, string $newName): Book
|
||||||
{
|
{
|
||||||
@@ -74,11 +75,11 @@ class Cloner
|
|||||||
// Clone contents
|
// Clone contents
|
||||||
$directChildren = $original->getDirectVisibleChildren();
|
$directChildren = $original->getDirectVisibleChildren();
|
||||||
foreach ($directChildren as $child) {
|
foreach ($directChildren as $child) {
|
||||||
if ($child instanceof Chapter && userCan('chapter-create', $copyBook)) {
|
if ($child instanceof Chapter && userCan(Permission::ChapterCreate, $copyBook)) {
|
||||||
$this->cloneChapter($child, $copyBook, $child->name);
|
$this->cloneChapter($child, $copyBook, $child->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($child instanceof Page && !$child->draft && userCan('page-create', $copyBook)) {
|
if ($child instanceof Page && !$child->draft && userCan(Permission::PageCreate, $copyBook)) {
|
||||||
$this->clonePage($child, $copyBook, $child->name);
|
$this->clonePage($child, $copyBook, $child->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ class Cloner
|
|||||||
// Clone bookshelf relationships
|
// Clone bookshelf relationships
|
||||||
/** @var Bookshelf $shelf */
|
/** @var Bookshelf $shelf */
|
||||||
foreach ($original->shelves as $shelf) {
|
foreach ($original->shelves as $shelf) {
|
||||||
if (userCan('bookshelf-update', $shelf)) {
|
if (userCan(Permission::BookshelfUpdate, $shelf)) {
|
||||||
$shelf->appendBook($copyBook);
|
$shelf->appendBook($copyBook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Entities\Queries\PageQueries;
|
|||||||
use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
|
use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Facades\Theme;
|
use BookStack\Facades\Theme;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Theming\ThemeEvents;
|
use BookStack\Theming\ThemeEvents;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Uploads\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
@@ -122,7 +123,7 @@ class PageContent
|
|||||||
$imageInfo = $this->parseBase64ImageUri($uri);
|
$imageInfo = $this->parseBase64ImageUri($uri);
|
||||||
|
|
||||||
// Validate user has permission to create images
|
// Validate user has permission to create images
|
||||||
if (!$updater->can('image-create-all')) {
|
if (!$updater->can(Permission::ImageCreateAll)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Entities\Models\Page;
|
|||||||
use BookStack\Entities\Queries\EntityQueries;
|
use BookStack\Entities\Queries\EntityQueries;
|
||||||
use BookStack\Entities\Tools\Markdown\HtmlToMarkdown;
|
use BookStack\Entities\Tools\Markdown\HtmlToMarkdown;
|
||||||
use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
|
use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class PageEditorData
|
class PageEditorData
|
||||||
{
|
{
|
||||||
@@ -98,9 +99,9 @@ class PageEditorData
|
|||||||
{
|
{
|
||||||
$editorType = PageEditorType::forPage($page) ?: PageEditorType::getSystemDefault();
|
$editorType = PageEditorType::forPage($page) ?: PageEditorType::getSystemDefault();
|
||||||
|
|
||||||
// Use requested editor if valid and if we have permission
|
// Use the requested editor if valid and if we have permission
|
||||||
$requestedType = PageEditorType::fromRequestValue($this->requestedEditor);
|
$requestedType = PageEditorType::fromRequestValue($this->requestedEditor);
|
||||||
if ($requestedType && userCan('editor-change')) {
|
if ($requestedType && userCan(Permission::EditorChange)) {
|
||||||
$editorType = $requestedType;
|
$editorType = $requestedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Entities\Models\Bookshelf;
|
|||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
use BookStack\Permissions\Models\EntityPermission;
|
use BookStack\Permissions\Models\EntityPermission;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\Role;
|
use BookStack\Users\Models\Role;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -93,8 +94,9 @@ class PermissionsUpdater
|
|||||||
|
|
||||||
foreach ($permissions as $roleId => $info) {
|
foreach ($permissions as $roleId => $info) {
|
||||||
$entityPermissionData = ['role_id' => $roleId];
|
$entityPermissionData = ['role_id' => $roleId];
|
||||||
foreach (EntityPermission::PERMISSIONS as $permission) {
|
foreach (Permission::genericForEntity() as $permission) {
|
||||||
$entityPermissionData[$permission] = (($info[$permission] ?? false) === "true");
|
$permName = $permission->value;
|
||||||
|
$entityPermissionData[$permName] = (($info[$permName] ?? false) === "true");
|
||||||
}
|
}
|
||||||
$formatted[] = $entityPermissionData;
|
$formatted[] = $entityPermissionData;
|
||||||
}
|
}
|
||||||
@@ -108,8 +110,9 @@ class PermissionsUpdater
|
|||||||
|
|
||||||
foreach ($permissions as $requestPermissionData) {
|
foreach ($permissions as $requestPermissionData) {
|
||||||
$entityPermissionData = ['role_id' => $requestPermissionData['role_id']];
|
$entityPermissionData = ['role_id' => $requestPermissionData['role_id']];
|
||||||
foreach (EntityPermission::PERMISSIONS as $permission) {
|
foreach (Permission::genericForEntity() as $permission) {
|
||||||
$entityPermissionData[$permission] = boolval($requestPermissionData[$permission] ?? false);
|
$permName = $permission->value;
|
||||||
|
$entityPermissionData[$permName] = boolval($requestPermissionData[$permName] ?? false);
|
||||||
}
|
}
|
||||||
$formatted[] = $entityPermissionData;
|
$formatted[] = $entityPermissionData;
|
||||||
}
|
}
|
||||||
@@ -147,7 +150,7 @@ class PermissionsUpdater
|
|||||||
|
|
||||||
/** @var Book $book */
|
/** @var Book $book */
|
||||||
foreach ($shelfBooks as $book) {
|
foreach ($shelfBooks as $book) {
|
||||||
if ($checkUserPermissions && !userCan('restrictions-manage', $book)) {
|
if ($checkUserPermissions && !userCan(Permission::RestrictionsManage, $book)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$book->permissions()->delete();
|
$book->permissions()->delete();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Entities\Queries\BookQueries;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class BookExportApiController extends ApiController
|
class BookExportApiController extends ApiController
|
||||||
@@ -14,7 +15,7 @@ class BookExportApiController extends ApiController
|
|||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
protected BookQueries $queries,
|
protected BookQueries $queries,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Exceptions\NotFoundException;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class BookExportController extends Controller
|
class BookExportController extends Controller
|
||||||
@@ -15,7 +16,7 @@ class BookExportController extends Controller
|
|||||||
protected BookQueries $queries,
|
protected BookQueries $queries,
|
||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
$this->middleware('throttle:exports');
|
$this->middleware('throttle:exports');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Entities\Queries\ChapterQueries;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class ChapterExportApiController extends ApiController
|
class ChapterExportApiController extends ApiController
|
||||||
@@ -14,7 +15,7 @@ class ChapterExportApiController extends ApiController
|
|||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
protected ChapterQueries $queries,
|
protected ChapterQueries $queries,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Exceptions\NotFoundException;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class ChapterExportController extends Controller
|
class ChapterExportController extends Controller
|
||||||
@@ -15,7 +16,7 @@ class ChapterExportController extends Controller
|
|||||||
protected ChapterQueries $queries,
|
protected ChapterQueries $queries,
|
||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
$this->middleware('throttle:exports');
|
$this->middleware('throttle:exports');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Exceptions\ZipImportException;
|
|||||||
use BookStack\Exceptions\ZipValidationException;
|
use BookStack\Exceptions\ZipValidationException;
|
||||||
use BookStack\Exports\ImportRepo;
|
use BookStack\Exports\ImportRepo;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -18,7 +19,7 @@ class ImportApiController extends ApiController
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
protected ImportRepo $imports,
|
protected ImportRepo $imports,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-import');
|
$this->middleware(Permission::ContentImport->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Exceptions\ZipImportException;
|
|||||||
use BookStack\Exceptions\ZipValidationException;
|
use BookStack\Exceptions\ZipValidationException;
|
||||||
use BookStack\Exports\ImportRepo;
|
use BookStack\Exports\ImportRepo;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ class ImportController extends Controller
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
protected ImportRepo $imports,
|
protected ImportRepo $imports,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-import');
|
$this->middleware(Permission::ContentImport->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Entities\Queries\PageQueries;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class PageExportApiController extends ApiController
|
class PageExportApiController extends ApiController
|
||||||
@@ -14,7 +15,7 @@ class PageExportApiController extends ApiController
|
|||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
protected PageQueries $queries,
|
protected PageQueries $queries,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Exceptions\NotFoundException;
|
|||||||
use BookStack\Exports\ExportFormatter;
|
use BookStack\Exports\ExportFormatter;
|
||||||
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
use BookStack\Exports\ZipExports\ZipExportBuilder;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class PageExportController extends Controller
|
class PageExportController extends Controller
|
||||||
@@ -16,7 +17,7 @@ class PageExportController extends Controller
|
|||||||
protected PageQueries $queries,
|
protected PageQueries $queries,
|
||||||
protected ExportFormatter $exportFormatter,
|
protected ExportFormatter $exportFormatter,
|
||||||
) {
|
) {
|
||||||
$this->middleware('can:content-export');
|
$this->middleware(Permission::ContentExport->middleware());
|
||||||
$this->middleware('throttle:exports');
|
$this->middleware('throttle:exports');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use BookStack\Exports\ZipExports\ZipExportReader;
|
|||||||
use BookStack\Exports\ZipExports\ZipExportValidator;
|
use BookStack\Exports\ZipExports\ZipExportValidator;
|
||||||
use BookStack\Exports\ZipExports\ZipImportRunner;
|
use BookStack\Exports\ZipExports\ZipImportRunner;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\FileStorage;
|
use BookStack\Uploads\FileStorage;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
@@ -46,7 +47,7 @@ class ImportRepo
|
|||||||
{
|
{
|
||||||
$query = Import::query();
|
$query = Import::query();
|
||||||
|
|
||||||
if (!userCan('settings-manage')) {
|
if (!userCan(Permission::SettingsManage)) {
|
||||||
$query->where('created_by', user()->id);
|
$query->where('created_by', user()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ class ImportRepo
|
|||||||
{
|
{
|
||||||
$query = Import::query();
|
$query = Import::query();
|
||||||
|
|
||||||
if (!userCan('settings-manage')) {
|
if (!userCan(Permission::SettingsManage)) {
|
||||||
$query->where('created_by', user()->id);
|
$query->where('created_by', user()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use BookStack\Exports\ZipExports\Models\ZipExportChapter;
|
|||||||
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportModel;
|
use BookStack\Exports\ZipExports\Models\ZipExportModel;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Attachment;
|
use BookStack\Uploads\Attachment;
|
||||||
use BookStack\Uploads\Image;
|
use BookStack\Uploads\Image;
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ class ZipExportReferences
|
|||||||
// Find and include images if in visibility
|
// Find and include images if in visibility
|
||||||
$page = $model->getPage();
|
$page = $model->getPage();
|
||||||
$pageExportModel = $this->pages[$page->id] ?? ($exportModel instanceof ZipExportPage ? $exportModel : null);
|
$pageExportModel = $this->pages[$page->id] ?? ($exportModel instanceof ZipExportPage ? $exportModel : null);
|
||||||
if (isset($this->images[$model->id]) || ($page && $pageExportModel && userCan('view', $page))) {
|
if (isset($this->images[$model->id]) || ($page && $pageExportModel && userCan(Permission::PageView, $page))) {
|
||||||
if (!isset($this->images[$model->id])) {
|
if (!isset($this->images[$model->id])) {
|
||||||
$exportImage = ZipExportImage::fromModel($model, $files);
|
$exportImage = ZipExportImage::fromModel($model, $files);
|
||||||
$this->images[$model->id] = $exportImage;
|
$this->images[$model->id] = $exportImage;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use BookStack\Exports\ZipExports\Models\ZipExportChapter;
|
|||||||
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportTag;
|
use BookStack\Exports\ZipExports\Models\ZipExportTag;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Attachment;
|
use BookStack\Uploads\Attachment;
|
||||||
use BookStack\Uploads\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use BookStack\Uploads\FileStorage;
|
use BookStack\Uploads\FileStorage;
|
||||||
@@ -288,7 +289,7 @@ class ZipImportRunner
|
|||||||
$attachments = [];
|
$attachments = [];
|
||||||
|
|
||||||
if ($exportModel instanceof ZipExportBook) {
|
if ($exportModel instanceof ZipExportBook) {
|
||||||
if (!userCan('book-create-all')) {
|
if (!userCan(Permission::BookCreateAll)) {
|
||||||
$errors[] = trans('errors.import_perms_books');
|
$errors[] = trans('errors.import_perms_books');
|
||||||
}
|
}
|
||||||
array_push($pages, ...$exportModel->pages);
|
array_push($pages, ...$exportModel->pages);
|
||||||
@@ -317,11 +318,11 @@ class ZipImportRunner
|
|||||||
|
|
||||||
if (count($pages) > 0) {
|
if (count($pages) > 0) {
|
||||||
if ($parent) {
|
if ($parent) {
|
||||||
if (!userCan('page-create', $parent)) {
|
if (!userCan(Permission::PageCreate, $parent)) {
|
||||||
$errors[] = trans('errors.import_perms_pages');
|
$errors[] = trans('errors.import_perms_pages');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$hasPermission = userCan('page-create-all') || userCan('page-create-own');
|
$hasPermission = userCan(Permission::PageCreateAll) || userCan(Permission::PageCreateOwn);
|
||||||
if (!$hasPermission) {
|
if (!$hasPermission) {
|
||||||
$errors[] = trans('errors.import_perms_pages');
|
$errors[] = trans('errors.import_perms_pages');
|
||||||
}
|
}
|
||||||
@@ -329,13 +330,13 @@ class ZipImportRunner
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count($images) > 0) {
|
if (count($images) > 0) {
|
||||||
if (!userCan('image-create-all')) {
|
if (!userCan(Permission::ImageCreateAll)) {
|
||||||
$errors[] = trans('errors.import_perms_images');
|
$errors[] = trans('errors.import_perms_images');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($attachments) > 0) {
|
if (count($attachments) > 0) {
|
||||||
if (!userCan('attachment-create-all')) {
|
if (!userCan(Permission::AttachmentCreateAll)) {
|
||||||
$errors[] = trans('errors.import_perms_attachments');
|
$errors[] = trans('errors.import_perms_attachments');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Activity\Models\Loggable;
|
|||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\Exceptions\NotifyException;
|
use BookStack\Exceptions\NotifyException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -27,10 +28,9 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the application and shows a permission error if
|
* Stops the application and shows a permission error if the application is in demo mode.
|
||||||
* the application is in demo mode.
|
|
||||||
*/
|
*/
|
||||||
protected function preventAccessInDemoMode()
|
protected function preventAccessInDemoMode(): void
|
||||||
{
|
{
|
||||||
if (config('app.env') === 'demo') {
|
if (config('app.env') === 'demo') {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
@@ -40,14 +40,13 @@ abstract class Controller extends BaseController
|
|||||||
/**
|
/**
|
||||||
* Adds the page title into the view.
|
* Adds the page title into the view.
|
||||||
*/
|
*/
|
||||||
public function setPageTitle(string $title)
|
public function setPageTitle(string $title): void
|
||||||
{
|
{
|
||||||
view()->share('pageTitle', $title);
|
view()->share('pageTitle', $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On a permission error redirect to home and display.
|
* On a permission error redirect to home and display the error as a notification.
|
||||||
* the error as a notification.
|
|
||||||
*
|
*
|
||||||
* @throws NotifyException
|
* @throws NotifyException
|
||||||
*/
|
*/
|
||||||
@@ -61,7 +60,7 @@ abstract class Controller extends BaseController
|
|||||||
/**
|
/**
|
||||||
* Checks that the current user has the given permission otherwise throw an exception.
|
* Checks that the current user has the given permission otherwise throw an exception.
|
||||||
*/
|
*/
|
||||||
protected function checkPermission(string $permission): void
|
protected function checkPermission(string|Permission $permission): void
|
||||||
{
|
{
|
||||||
if (!user() || !user()->can($permission)) {
|
if (!user() || !user()->can($permission)) {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
@@ -81,7 +80,7 @@ abstract class Controller extends BaseController
|
|||||||
/**
|
/**
|
||||||
* Check the current user's permissions against an ownable item otherwise throw an exception.
|
* Check the current user's permissions against an ownable item otherwise throw an exception.
|
||||||
*/
|
*/
|
||||||
protected function checkOwnablePermission(string $permission, Model $ownable, string $redirectLocation = '/'): void
|
protected function checkOwnablePermission(string|Permission $permission, Model $ownable, string $redirectLocation = '/'): void
|
||||||
{
|
{
|
||||||
if (!userCan($permission, $ownable)) {
|
if (!userCan($permission, $ownable)) {
|
||||||
$this->showPermissionError($redirectLocation);
|
$this->showPermissionError($redirectLocation);
|
||||||
@@ -92,7 +91,7 @@ abstract class Controller extends BaseController
|
|||||||
* Check if a user has a permission or bypass the permission
|
* Check if a user has a permission or bypass the permission
|
||||||
* check if the given callback resolves true.
|
* check if the given callback resolves true.
|
||||||
*/
|
*/
|
||||||
protected function checkPermissionOr(string $permission, callable $callback): void
|
protected function checkPermissionOr(string|Permission $permission, callable $callback): void
|
||||||
{
|
{
|
||||||
if ($callback() !== true) {
|
if ($callback() !== true) {
|
||||||
$this->checkPermission($permission);
|
$this->checkPermission($permission);
|
||||||
@@ -103,7 +102,7 @@ abstract class Controller extends BaseController
|
|||||||
* Check if the current user has a permission or bypass if the provided user
|
* Check if the current user has a permission or bypass if the provided user
|
||||||
* id matches the current user.
|
* id matches the current user.
|
||||||
*/
|
*/
|
||||||
protected function checkPermissionOrCurrentUser(string $permission, int $userId): void
|
protected function checkPermissionOrCurrentUser(string|Permission $permission, int $userId): void
|
||||||
{
|
{
|
||||||
$this->checkPermissionOr($permission, function () use ($userId) {
|
$this->checkPermissionOr($permission, function () use ($userId) {
|
||||||
return $userId === user()->id;
|
return $userId === user()->id;
|
||||||
@@ -111,7 +110,7 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send back a json error message.
|
* Send back a JSON error message.
|
||||||
*/
|
*/
|
||||||
protected function jsonError(string $messageText = '', int $statusCode = 500): JsonResponse
|
protected function jsonError(string $messageText = '', int $statusCode = 500): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -127,7 +126,7 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a positive, successful notification to the user on next view load.
|
* Show a positive, successful notification to the user on the next view load.
|
||||||
*/
|
*/
|
||||||
protected function showSuccessNotification(string $message): void
|
protected function showSuccessNotification(string $message): void
|
||||||
{
|
{
|
||||||
@@ -135,7 +134,7 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a warning notification to the user on next view load.
|
* Show a warning notification to the user on the next view load.
|
||||||
*/
|
*/
|
||||||
protected function showWarningNotification(string $message): void
|
protected function showWarningNotification(string $message): void
|
||||||
{
|
{
|
||||||
@@ -143,7 +142,7 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an error notification to the user on next view load.
|
* Show an error notification to the user on the next view load.
|
||||||
*/
|
*/
|
||||||
protected function showErrorNotification(string $message): void
|
protected function showErrorNotification(string $message): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Http\Middleware;
|
namespace BookStack\Http\Middleware;
|
||||||
|
|
||||||
use BookStack\Exceptions\ApiAuthException;
|
use BookStack\Exceptions\ApiAuthException;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ class ApiAuthenticate
|
|||||||
*/
|
*/
|
||||||
protected function sessionUserHasApiAccess(): bool
|
protected function sessionUserHasApiAccess(): bool
|
||||||
{
|
{
|
||||||
$hasApiPermission = user()->can('access-api');
|
$hasApiPermission = user()->can(Permission::AccessApi);
|
||||||
|
|
||||||
return $hasApiPermission && user()->hasAppAccess();
|
return $hasApiPermission && user()->hasAppAccess();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Http\Middleware;
|
namespace BookStack\Http\Middleware;
|
||||||
|
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -10,13 +11,9 @@ class CheckUserHasPermission
|
|||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @param string $permission
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next, $permission)
|
public function handle(Request $request, Closure $next, string|Permission $permission)
|
||||||
{
|
{
|
||||||
if (!user()->can($permission)) {
|
if (!user()->can($permission)) {
|
||||||
return $this->errorResponse($request);
|
return $this->errorResponse($request);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ContentPermissionApiController extends ApiController
|
|||||||
$entity = $this->entities->get($contentType)
|
$entity = $this->entities->get($contentType)
|
||||||
->newQuery()->scopes(['visible'])->findOrFail($contentId);
|
->newQuery()->scopes(['visible'])->findOrFail($contentId);
|
||||||
|
|
||||||
$this->checkOwnablePermission('restrictions-manage', $entity);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $entity);
|
||||||
|
|
||||||
return response()->json($this->formattedPermissionDataForEntity($entity));
|
return response()->json($this->formattedPermissionDataForEntity($entity));
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ class ContentPermissionApiController extends ApiController
|
|||||||
$entity = $this->entities->get($contentType)
|
$entity = $this->entities->get($contentType)
|
||||||
->newQuery()->scopes(['visible'])->findOrFail($contentId);
|
->newQuery()->scopes(['visible'])->findOrFail($contentId);
|
||||||
|
|
||||||
$this->checkOwnablePermission('restrictions-manage', $entity);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $entity);
|
||||||
|
|
||||||
$data = $this->validate($request, $this->rules()['update']);
|
$data = $this->validate($request, $this->rules()['update']);
|
||||||
$this->permissionsUpdater->updateFromApiRequestData($entity, $data);
|
$this->permissionsUpdater->updateFromApiRequestData($entity, $data);
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
*/
|
*/
|
||||||
class EntityPermission extends Model
|
class EntityPermission extends Model
|
||||||
{
|
{
|
||||||
public const PERMISSIONS = ['view', 'create', 'update', 'delete'];
|
|
||||||
|
|
||||||
protected $fillable = ['role_id', 'view', 'create', 'update', 'delete'];
|
protected $fillable = ['role_id', 'view', 'create', 'update', 'delete'];
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
protected $hidden = ['entity_id', 'entity_type', 'id'];
|
protected $hidden = ['entity_id', 'entity_type', 'id'];
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string $display_name
|
|
||||||
*/
|
*/
|
||||||
class RolePermission extends Model
|
class RolePermission extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
144
app/Permissions/Permission.php
Normal file
144
app/Permissions/Permission.php
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum to represent the permissions which may be used in checks.
|
||||||
|
* These generally align with RolePermission names, although some are abstract or truncated as some checks
|
||||||
|
* are performed across a range of different items which may be subject to inheritance and other complications.
|
||||||
|
*
|
||||||
|
* We use and still allow the string values in usage to allow for compatibility with scenarios where
|
||||||
|
* users have customised their instance with additional permissions via the theme system.
|
||||||
|
* This enum primarily exists for alignment within the codebase.
|
||||||
|
*
|
||||||
|
* Permissions with all/own suffixes may also be represented as a higher-level alias without the own/all
|
||||||
|
* suffix, which are used and assessed in the permission system logic.
|
||||||
|
*/
|
||||||
|
enum Permission: string
|
||||||
|
{
|
||||||
|
// Generic Actions
|
||||||
|
// Used for more abstract entity permission checks
|
||||||
|
case View = 'view';
|
||||||
|
case Create = 'create';
|
||||||
|
case Update = 'update';
|
||||||
|
case Delete = 'delete';
|
||||||
|
|
||||||
|
// System Permissions
|
||||||
|
case AccessApi = 'access-api';
|
||||||
|
case ContentExport = 'content-export';
|
||||||
|
case ContentImport = 'content-import';
|
||||||
|
case EditorChange = 'editor-change';
|
||||||
|
case ReceiveNotifications = 'receive-notifications';
|
||||||
|
case RestrictionsManage = 'restrictions-manage';
|
||||||
|
case RestrictionsManageAll = 'restrictions-manage-all';
|
||||||
|
case RestrictionsManageOwn = 'restrictions-manage-own';
|
||||||
|
case SettingsManage = 'settings-manage';
|
||||||
|
case TemplatesManage = 'templates-manage';
|
||||||
|
case UserRolesManage = 'user-roles-manage';
|
||||||
|
case UsersManage = 'users-manage';
|
||||||
|
|
||||||
|
// Non-entity content permissions
|
||||||
|
case AttachmentCreate = 'attachment-create';
|
||||||
|
case AttachmentCreateAll = 'attachment-create-all';
|
||||||
|
case AttachmentCreateOwn = 'attachment-create-own';
|
||||||
|
case AttachmentDelete = 'attachment-delete';
|
||||||
|
case AttachmentDeleteAll = 'attachment-delete-all';
|
||||||
|
case AttachmentDeleteOwn = 'attachment-delete-own';
|
||||||
|
case AttachmentUpdate = 'attachment-update';
|
||||||
|
case AttachmentUpdateAll = 'attachment-update-all';
|
||||||
|
case AttachmentUpdateOwn = 'attachment-update-own';
|
||||||
|
|
||||||
|
case CommentCreate = 'comment-create';
|
||||||
|
case CommentCreateAll = 'comment-create-all';
|
||||||
|
case CommentCreateOwn = 'comment-create-own';
|
||||||
|
case CommentDelete = 'comment-delete';
|
||||||
|
case CommentDeleteAll = 'comment-delete-all';
|
||||||
|
case CommentDeleteOwn = 'comment-delete-own';
|
||||||
|
case CommentUpdate = 'comment-update';
|
||||||
|
case CommentUpdateAll = 'comment-update-all';
|
||||||
|
case CommentUpdateOwn = 'comment-update-own';
|
||||||
|
|
||||||
|
case ImageCreateAll = 'image-create-all';
|
||||||
|
case ImageCreateOwn = 'image-create-own';
|
||||||
|
case ImageDelete = 'image-delete';
|
||||||
|
case ImageDeleteAll = 'image-delete-all';
|
||||||
|
case ImageDeleteOwn = 'image-delete-own';
|
||||||
|
case ImageUpdate = 'image-update';
|
||||||
|
case ImageUpdateAll = 'image-update-all';
|
||||||
|
case ImageUpdateOwn = 'image-update-own';
|
||||||
|
|
||||||
|
// Entity content permissions
|
||||||
|
case BookCreate = 'book-create';
|
||||||
|
case BookCreateAll = 'book-create-all';
|
||||||
|
case BookCreateOwn = 'book-create-own';
|
||||||
|
case BookDelete = 'book-delete';
|
||||||
|
case BookDeleteAll = 'book-delete-all';
|
||||||
|
case BookDeleteOwn = 'book-delete-own';
|
||||||
|
case BookUpdate = 'book-update';
|
||||||
|
case BookUpdateAll = 'book-update-all';
|
||||||
|
case BookUpdateOwn = 'book-update-own';
|
||||||
|
case BookView = 'book-view';
|
||||||
|
case BookViewAll = 'book-view-all';
|
||||||
|
case BookViewOwn = 'book-view-own';
|
||||||
|
|
||||||
|
case BookshelfCreate = 'bookshelf-create';
|
||||||
|
case BookshelfCreateAll = 'bookshelf-create-all';
|
||||||
|
case BookshelfCreateOwn = 'bookshelf-create-own';
|
||||||
|
case BookshelfDelete = 'bookshelf-delete';
|
||||||
|
case BookshelfDeleteAll = 'bookshelf-delete-all';
|
||||||
|
case BookshelfDeleteOwn = 'bookshelf-delete-own';
|
||||||
|
case BookshelfUpdate = 'bookshelf-update';
|
||||||
|
case BookshelfUpdateAll = 'bookshelf-update-all';
|
||||||
|
case BookshelfUpdateOwn = 'bookshelf-update-own';
|
||||||
|
case BookshelfView = 'bookshelf-view';
|
||||||
|
case BookshelfViewAll = 'bookshelf-view-all';
|
||||||
|
case BookshelfViewOwn = 'bookshelf-view-own';
|
||||||
|
|
||||||
|
case ChapterCreate = 'chapter-create';
|
||||||
|
case ChapterCreateAll = 'chapter-create-all';
|
||||||
|
case ChapterCreateOwn = 'chapter-create-own';
|
||||||
|
case ChapterDelete = 'chapter-delete';
|
||||||
|
case ChapterDeleteAll = 'chapter-delete-all';
|
||||||
|
case ChapterDeleteOwn = 'chapter-delete-own';
|
||||||
|
case ChapterUpdate = 'chapter-update';
|
||||||
|
case ChapterUpdateAll = 'chapter-update-all';
|
||||||
|
case ChapterUpdateOwn = 'chapter-update-own';
|
||||||
|
case ChapterView = 'chapter-view';
|
||||||
|
case ChapterViewAll = 'chapter-view-all';
|
||||||
|
case ChapterViewOwn = 'chapter-view-own';
|
||||||
|
|
||||||
|
case PageCreate = 'page-create';
|
||||||
|
case PageCreateAll = 'page-create-all';
|
||||||
|
case PageCreateOwn = 'page-create-own';
|
||||||
|
case PageDelete = 'page-delete';
|
||||||
|
case PageDeleteAll = 'page-delete-all';
|
||||||
|
case PageDeleteOwn = 'page-delete-own';
|
||||||
|
case PageUpdate = 'page-update';
|
||||||
|
case PageUpdateAll = 'page-update-all';
|
||||||
|
case PageUpdateOwn = 'page-update-own';
|
||||||
|
case PageView = 'page-view';
|
||||||
|
case PageViewAll = 'page-view-all';
|
||||||
|
case PageViewOwn = 'page-view-own';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the generic permissions which may be queried for entities.
|
||||||
|
*/
|
||||||
|
public static function genericForEntity(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::View,
|
||||||
|
self::Create,
|
||||||
|
self::Update,
|
||||||
|
self::Delete,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the application permission-check middleware-string for this permission.
|
||||||
|
* Uses registered CheckUserHasPermission middleware.
|
||||||
|
*/
|
||||||
|
public function middleware(): string
|
||||||
|
{
|
||||||
|
return 'can:' . $this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,11 +24,12 @@ class PermissionApplicator
|
|||||||
/**
|
/**
|
||||||
* Checks if an entity has a restriction set upon it.
|
* Checks if an entity has a restriction set upon it.
|
||||||
*/
|
*/
|
||||||
public function checkOwnableUserAccess(Model&OwnableInterface $ownable, string $permission): bool
|
public function checkOwnableUserAccess(Model&OwnableInterface $ownable, string|Permission $permission): bool
|
||||||
{
|
{
|
||||||
$explodedPermission = explode('-', $permission);
|
$permissionName = is_string($permission) ? $permission : $permission->value;
|
||||||
|
$explodedPermission = explode('-', $permissionName);
|
||||||
$action = $explodedPermission[1] ?? $explodedPermission[0];
|
$action = $explodedPermission[1] ?? $explodedPermission[0];
|
||||||
$fullPermission = count($explodedPermission) > 1 ? $permission : $ownable->getMorphClass() . '-' . $permission;
|
$fullPermission = count($explodedPermission) > 1 ? $permissionName : $ownable->getMorphClass() . '-' . $permissionName;
|
||||||
|
|
||||||
$user = $this->currentUser();
|
$user = $this->currentUser();
|
||||||
$userRoleIds = $this->getCurrentUserRoleIds();
|
$userRoleIds = $this->getCurrentUserRoleIds();
|
||||||
@@ -75,12 +76,13 @@ class PermissionApplicator
|
|||||||
* Checks if a user has the given permission for any items in the system.
|
* Checks if a user has the given permission for any items in the system.
|
||||||
* Can be passed an entity instance to filter on a specific type.
|
* Can be passed an entity instance to filter on a specific type.
|
||||||
*/
|
*/
|
||||||
public function checkUserHasEntityPermissionOnAny(string $action, string $entityClass = ''): bool
|
public function checkUserHasEntityPermissionOnAny(string|Permission $action, string $entityClass = ''): bool
|
||||||
{
|
{
|
||||||
$this->ensureValidEntityAction($action);
|
$permissionName = is_string($action) ? $action : $action->value;
|
||||||
|
$this->ensureValidEntityAction($permissionName);
|
||||||
|
|
||||||
$permissionQuery = EntityPermission::query()
|
$permissionQuery = EntityPermission::query()
|
||||||
->where($action, '=', true)
|
->where($permissionName, '=', true)
|
||||||
->whereIn('role_id', $this->getCurrentUserRoleIds());
|
->whereIn('role_id', $this->getCurrentUserRoleIds());
|
||||||
|
|
||||||
if (!empty($entityClass)) {
|
if (!empty($entityClass)) {
|
||||||
@@ -235,8 +237,13 @@ class PermissionApplicator
|
|||||||
*/
|
*/
|
||||||
protected function ensureValidEntityAction(string $action): void
|
protected function ensureValidEntityAction(string $action): void
|
||||||
{
|
{
|
||||||
if (!in_array($action, EntityPermission::PERMISSIONS)) {
|
$allowed = Permission::genericForEntity();
|
||||||
throw new InvalidArgumentException('Action should be a simple entity permission action, not a role permission');
|
foreach ($allowed as $permission) {
|
||||||
|
if ($permission->value === $action) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new InvalidArgumentException('Action should be a simple entity permission action, not a role permission');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class PermissionsController extends Controller
|
|||||||
public function showForPage(string $bookSlug, string $pageSlug)
|
public function showForPage(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $page);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $page);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.pages_permissions'));
|
$this->setPageTitle(trans('entities.pages_permissions'));
|
||||||
return view('pages.permissions', [
|
return view('pages.permissions', [
|
||||||
@@ -39,7 +39,7 @@ class PermissionsController extends Controller
|
|||||||
public function updateForPage(Request $request, string $bookSlug, string $pageSlug)
|
public function updateForPage(Request $request, string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
$page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $page);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $page);
|
||||||
|
|
||||||
(new DatabaseTransaction(function () use ($page, $request) {
|
(new DatabaseTransaction(function () use ($page, $request) {
|
||||||
$this->permissionsUpdater->updateFromPermissionsForm($page, $request);
|
$this->permissionsUpdater->updateFromPermissionsForm($page, $request);
|
||||||
@@ -56,7 +56,7 @@ class PermissionsController extends Controller
|
|||||||
public function showForChapter(string $bookSlug, string $chapterSlug)
|
public function showForChapter(string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $chapter);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $chapter);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.chapters_permissions'));
|
$this->setPageTitle(trans('entities.chapters_permissions'));
|
||||||
return view('chapters.permissions', [
|
return view('chapters.permissions', [
|
||||||
@@ -71,7 +71,7 @@ class PermissionsController extends Controller
|
|||||||
public function updateForChapter(Request $request, string $bookSlug, string $chapterSlug)
|
public function updateForChapter(Request $request, string $bookSlug, string $chapterSlug)
|
||||||
{
|
{
|
||||||
$chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
$chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $chapter);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $chapter);
|
||||||
|
|
||||||
(new DatabaseTransaction(function () use ($chapter, $request) {
|
(new DatabaseTransaction(function () use ($chapter, $request) {
|
||||||
$this->permissionsUpdater->updateFromPermissionsForm($chapter, $request);
|
$this->permissionsUpdater->updateFromPermissionsForm($chapter, $request);
|
||||||
@@ -88,7 +88,7 @@ class PermissionsController extends Controller
|
|||||||
public function showForBook(string $slug)
|
public function showForBook(string $slug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->books->findVisibleBySlugOrFail($slug);
|
$book = $this->queries->books->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $book);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $book);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.books_permissions'));
|
$this->setPageTitle(trans('entities.books_permissions'));
|
||||||
return view('books.permissions', [
|
return view('books.permissions', [
|
||||||
@@ -103,7 +103,7 @@ class PermissionsController extends Controller
|
|||||||
public function updateForBook(Request $request, string $slug)
|
public function updateForBook(Request $request, string $slug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->books->findVisibleBySlugOrFail($slug);
|
$book = $this->queries->books->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $book);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $book);
|
||||||
|
|
||||||
(new DatabaseTransaction(function () use ($book, $request) {
|
(new DatabaseTransaction(function () use ($book, $request) {
|
||||||
$this->permissionsUpdater->updateFromPermissionsForm($book, $request);
|
$this->permissionsUpdater->updateFromPermissionsForm($book, $request);
|
||||||
@@ -120,7 +120,7 @@ class PermissionsController extends Controller
|
|||||||
public function showForShelf(string $slug)
|
public function showForShelf(string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $shelf);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $shelf);
|
||||||
|
|
||||||
$this->setPageTitle(trans('entities.shelves_permissions'));
|
$this->setPageTitle(trans('entities.shelves_permissions'));
|
||||||
return view('shelves.permissions', [
|
return view('shelves.permissions', [
|
||||||
@@ -135,7 +135,7 @@ class PermissionsController extends Controller
|
|||||||
public function updateForShelf(Request $request, string $slug)
|
public function updateForShelf(Request $request, string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $shelf);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $shelf);
|
||||||
|
|
||||||
(new DatabaseTransaction(function () use ($shelf, $request) {
|
(new DatabaseTransaction(function () use ($shelf, $request) {
|
||||||
$this->permissionsUpdater->updateFromPermissionsForm($shelf, $request);
|
$this->permissionsUpdater->updateFromPermissionsForm($shelf, $request);
|
||||||
@@ -152,7 +152,7 @@ class PermissionsController extends Controller
|
|||||||
public function copyShelfPermissionsToBooks(string $slug)
|
public function copyShelfPermissionsToBooks(string $slug)
|
||||||
{
|
{
|
||||||
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
$shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $shelf);
|
$this->checkOwnablePermission(Permission::RestrictionsManage, $shelf);
|
||||||
|
|
||||||
$updateCount = (new DatabaseTransaction(function () use ($shelf) {
|
$updateCount = (new DatabaseTransaction(function () use ($shelf) {
|
||||||
return $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf);
|
return $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf);
|
||||||
@@ -168,7 +168,7 @@ class PermissionsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function formRowForRole(string $entityType, string $roleId)
|
public function formRowForRole(string $entityType, string $roleId)
|
||||||
{
|
{
|
||||||
$this->checkPermissionOr('restrictions-manage-all', fn() => userCan('restrictions-manage-own'));
|
$this->checkPermissionOr(Permission::RestrictionsManageAll, fn() => userCan(Permission::RestrictionsManageOwn));
|
||||||
|
|
||||||
$role = Role::query()->findOrFail($roleId);
|
$role = Role::query()->findOrFail($roleId);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Activity\ActivityType;
|
|||||||
use BookStack\App\AppVersion;
|
use BookStack\App\AppVersion;
|
||||||
use BookStack\Entities\Tools\TrashCan;
|
use BookStack\Entities\Tools\TrashCan;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\References\ReferenceStore;
|
use BookStack\References\ReferenceStore;
|
||||||
use BookStack\Uploads\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -17,7 +18,7 @@ class MaintenanceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(TrashCan $trashCan)
|
public function index(TrashCan $trashCan)
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->setPageTitle(trans('settings.maint'));
|
$this->setPageTitle(trans('settings.maint'));
|
||||||
|
|
||||||
// Recycle bin details
|
// Recycle bin details
|
||||||
@@ -34,7 +35,7 @@ class MaintenanceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function cleanupImages(Request $request, ImageService $imageService)
|
public function cleanupImages(Request $request, ImageService $imageService)
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'cleanup-images');
|
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'cleanup-images');
|
||||||
|
|
||||||
$checkRevisions = !($request->get('ignore_revisions', 'false') === 'true');
|
$checkRevisions = !($request->get('ignore_revisions', 'false') === 'true');
|
||||||
@@ -62,7 +63,7 @@ class MaintenanceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function sendTestEmail()
|
public function sendTestEmail()
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'send-test-email');
|
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'send-test-email');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -81,7 +82,7 @@ class MaintenanceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function regenerateReferences(ReferenceStore $referenceStore)
|
public function regenerateReferences(ReferenceStore $referenceStore)
|
||||||
{
|
{
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'regenerate-references');
|
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'regenerate-references');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace BookStack\Settings;
|
|||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\App\AppVersion;
|
use BookStack\App\AppVersion;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ class SettingController extends Controller
|
|||||||
public function category(string $category)
|
public function category(string $category)
|
||||||
{
|
{
|
||||||
$this->ensureCategoryExists($category);
|
$this->ensureCategoryExists($category);
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->setPageTitle(trans('settings.settings'));
|
$this->setPageTitle(trans('settings.settings'));
|
||||||
|
|
||||||
return view('settings.categories.' . $category, [
|
return view('settings.categories.' . $category, [
|
||||||
@@ -41,7 +42,7 @@ class SettingController extends Controller
|
|||||||
{
|
{
|
||||||
$this->ensureCategoryExists($category);
|
$this->ensureCategoryExists($category);
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
$this->checkPermission('settings-manage');
|
$this->checkPermission(Permission::SettingsManage);
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'app_logo' => ['nullable', ...$this->getImageValidationRules()],
|
'app_logo' => ['nullable', ...$this->getImageValidationRules()],
|
||||||
'app_icon' => ['nullable', ...$this->getImageValidationRules()],
|
'app_icon' => ['nullable', ...$this->getImageValidationRules()],
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Entities\Queries\BookQueries;
|
|||||||
use BookStack\Entities\Tools\BookContents;
|
use BookStack\Entities\Tools\BookContents;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Util\DatabaseTransaction;
|
use BookStack\Util\DatabaseTransaction;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ class BookSortController extends Controller
|
|||||||
public function show(string $bookSlug)
|
public function show(string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
|
|
||||||
$bookChildren = (new BookContents($book))->getTree(false);
|
$bookChildren = (new BookContents($book))->getTree(false);
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ class BookSortController extends Controller
|
|||||||
public function update(Request $request, BookSorter $sorter, string $bookSlug)
|
public function update(Request $request, BookSorter $sorter, string $bookSlug)
|
||||||
{
|
{
|
||||||
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
|
||||||
$this->checkOwnablePermission('book-update', $book);
|
$this->checkOwnablePermission(Permission::BookUpdate, $book);
|
||||||
$loggedActivityForBook = false;
|
$loggedActivityForBook = false;
|
||||||
|
|
||||||
// Sort via map
|
// Sort via map
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use BookStack\Entities\Models\Chapter;
|
|||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use BookStack\Entities\Queries\EntityQueries;
|
use BookStack\Entities\Queries\EntityQueries;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
|
|
||||||
class BookSorter
|
class BookSorter
|
||||||
{
|
{
|
||||||
@@ -187,11 +188,11 @@ class BookSorter
|
|||||||
|
|
||||||
$hasNewParent = $newBook->id !== $model->book_id || ($model instanceof Page && $model->chapter_id !== ($sortMapItem->parentChapterId ?? 0));
|
$hasNewParent = $newBook->id !== $model->book_id || ($model instanceof Page && $model->chapter_id !== ($sortMapItem->parentChapterId ?? 0));
|
||||||
if ($model instanceof Chapter) {
|
if ($model instanceof Chapter) {
|
||||||
$hasPermission = userCan('book-update', $currentParent)
|
$hasPermission = userCan(Permission::BookUpdate, $currentParent)
|
||||||
&& userCan('book-update', $newBook)
|
&& userCan(Permission::BookUpdate, $newBook)
|
||||||
&& userCan('chapter-update', $model)
|
&& userCan(Permission::ChapterUpdate, $model)
|
||||||
&& (!$hasNewParent || userCan('chapter-create', $newBook))
|
&& (!$hasNewParent || userCan(Permission::ChapterCreate, $newBook))
|
||||||
&& (!$hasNewParent || userCan('chapter-delete', $model));
|
&& (!$hasNewParent || userCan(Permission::ChapterDelete, $model));
|
||||||
|
|
||||||
if (!$hasPermission) {
|
if (!$hasPermission) {
|
||||||
return false;
|
return false;
|
||||||
@@ -210,13 +211,13 @@ class BookSorter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hasPageEditPermission = userCan('page-update', $model);
|
$hasPageEditPermission = userCan(Permission::PageUpdate, $model);
|
||||||
$newParentInRightLocation = ($newParent instanceof Book || ($newParent instanceof Chapter && $newParent->book_id === $newBook->id));
|
$newParentInRightLocation = ($newParent instanceof Book || ($newParent instanceof Chapter && $newParent->book_id === $newBook->id));
|
||||||
$newParentPermission = ($newParent instanceof Chapter) ? 'chapter-update' : 'book-update';
|
$newParentPermission = ($newParent instanceof Chapter) ? 'chapter-update' : 'book-update';
|
||||||
$hasNewParentPermission = userCan($newParentPermission, $newParent);
|
$hasNewParentPermission = userCan($newParentPermission, $newParent);
|
||||||
|
|
||||||
$hasDeletePermissionIfMoving = (!$hasNewParent || userCan('page-delete', $model));
|
$hasDeletePermissionIfMoving = (!$hasNewParent || userCan(Permission::PageDelete, $model));
|
||||||
$hasCreatePermissionIfMoving = (!$hasNewParent || userCan('page-create', $newParent));
|
$hasCreatePermissionIfMoving = (!$hasNewParent || userCan(Permission::PageCreate, $newParent));
|
||||||
|
|
||||||
$hasPermission = $hasCurrentParentPermission
|
$hasPermission = $hasCurrentParentPermission
|
||||||
&& $newParentInRightLocation
|
&& $newParentInRightLocation
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ namespace BookStack\Sorting;
|
|||||||
|
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class SortRuleController extends Controller
|
class SortRuleController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware('can:settings-manage');
|
$this->middleware(Permission::SettingsManage->middleware());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace BookStack\Uploads\Controllers;
|
|||||||
use BookStack\Entities\Queries\PageQueries;
|
use BookStack\Entities\Queries\PageQueries;
|
||||||
use BookStack\Exceptions\FileUploadException;
|
use BookStack\Exceptions\FileUploadException;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Attachment;
|
use BookStack\Uploads\Attachment;
|
||||||
use BookStack\Uploads\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -45,12 +46,12 @@ class AttachmentApiController extends ApiController
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('attachment-create-all');
|
$this->checkPermission(Permission::AttachmentCreateAll);
|
||||||
$requestData = $this->validate($request, $this->rules()['create']);
|
$requestData = $this->validate($request, $this->rules()['create']);
|
||||||
|
|
||||||
$pageId = $request->get('uploaded_to');
|
$pageId = $request->get('uploaded_to');
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
if ($request->hasFile('file')) {
|
||||||
$uploadedFile = $request->file('file');
|
$uploadedFile = $request->file('file');
|
||||||
@@ -137,9 +138,9 @@ class AttachmentApiController extends ApiController
|
|||||||
$attachment->uploaded_to = $requestData['uploaded_to'];
|
$attachment->uploaded_to = $requestData['uploaded_to'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
$this->checkOwnablePermission(Permission::PageView, $page);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
$this->checkOwnablePermission('attachment-update', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentUpdate, $attachment);
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
if ($request->hasFile('file')) {
|
||||||
$uploadedFile = $request->file('file');
|
$uploadedFile = $request->file('file');
|
||||||
@@ -160,7 +161,7 @@ class AttachmentApiController extends ApiController
|
|||||||
{
|
{
|
||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
$attachment = Attachment::visible()->findOrFail($id);
|
$attachment = Attachment::visible()->findOrFail($id);
|
||||||
$this->checkOwnablePermission('attachment-delete', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentDelete, $attachment);
|
||||||
|
|
||||||
$this->attachmentService->deleteFile($attachment);
|
$this->attachmentService->deleteFile($attachment);
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Entities\Repos\PageRepo;
|
|||||||
use BookStack\Exceptions\FileUploadException;
|
use BookStack\Exceptions\FileUploadException;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Attachment;
|
use BookStack\Uploads\Attachment;
|
||||||
use BookStack\Uploads\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -40,8 +41,8 @@ class AttachmentController extends Controller
|
|||||||
$pageId = $request->get('uploaded_to');
|
$pageId = $request->get('uploaded_to');
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
|
|
||||||
$this->checkPermission('attachment-create-all');
|
$this->checkPermission(Permission::AttachmentCreateAll);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$uploadedFile = $request->file('file');
|
$uploadedFile = $request->file('file');
|
||||||
|
|
||||||
@@ -67,9 +68,9 @@ class AttachmentController extends Controller
|
|||||||
|
|
||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||||
$this->checkOwnablePermission('view', $attachment->page);
|
$this->checkOwnablePermission(Permission::PageView, $attachment->page);
|
||||||
$this->checkOwnablePermission('page-update', $attachment->page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $attachment->page);
|
||||||
$this->checkOwnablePermission('attachment-create', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentUpdate, $attachment);
|
||||||
|
|
||||||
$uploadedFile = $request->file('file');
|
$uploadedFile = $request->file('file');
|
||||||
|
|
||||||
@@ -90,8 +91,8 @@ class AttachmentController extends Controller
|
|||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-update', $attachment->page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $attachment->page);
|
||||||
$this->checkOwnablePermission('attachment-create', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentCreate, $attachment);
|
||||||
|
|
||||||
return view('attachments.manager-edit-form', [
|
return view('attachments.manager-edit-form', [
|
||||||
'attachment' => $attachment,
|
'attachment' => $attachment,
|
||||||
@@ -118,9 +119,9 @@ class AttachmentController extends Controller
|
|||||||
]), 422);
|
]), 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-view', $attachment->page);
|
$this->checkOwnablePermission(Permission::PageView, $attachment->page);
|
||||||
$this->checkOwnablePermission('page-update', $attachment->page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $attachment->page);
|
||||||
$this->checkOwnablePermission('attachment-update', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentUpdate, $attachment);
|
||||||
|
|
||||||
$attachment = $this->attachmentService->updateFile($attachment, [
|
$attachment = $this->attachmentService->updateFile($attachment, [
|
||||||
'name' => $request->get('attachment_edit_name'),
|
'name' => $request->get('attachment_edit_name'),
|
||||||
@@ -156,8 +157,8 @@ class AttachmentController extends Controller
|
|||||||
|
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
|
|
||||||
$this->checkPermission('attachment-create-all');
|
$this->checkPermission(Permission::AttachmentCreateAll);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$attachmentName = $request->get('attachment_link_name');
|
$attachmentName = $request->get('attachment_link_name');
|
||||||
$link = $request->get('attachment_link_url');
|
$link = $request->get('attachment_link_url');
|
||||||
@@ -176,7 +177,6 @@ class AttachmentController extends Controller
|
|||||||
public function listForPage(int $pageId)
|
public function listForPage(int $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
|
||||||
|
|
||||||
return view('attachments.manager-list', [
|
return view('attachments.manager-list', [
|
||||||
'attachments' => $page->attachments->all(),
|
'attachments' => $page->attachments->all(),
|
||||||
@@ -195,7 +195,7 @@ class AttachmentController extends Controller
|
|||||||
'order' => ['required', 'array'],
|
'order' => ['required', 'array'],
|
||||||
]);
|
]);
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$attachmentOrder = $request->get('order');
|
$attachmentOrder = $request->get('order');
|
||||||
$this->attachmentService->updateFileOrderWithinPage($attachmentOrder, $pageId);
|
$this->attachmentService->updateFileOrderWithinPage($attachmentOrder, $pageId);
|
||||||
@@ -220,7 +220,7 @@ class AttachmentController extends Controller
|
|||||||
throw new NotFoundException(trans('errors.attachment_not_found'));
|
throw new NotFoundException(trans('errors.attachment_not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
$this->checkOwnablePermission(Permission::PageView, $page);
|
||||||
|
|
||||||
if ($attachment->external) {
|
if ($attachment->external) {
|
||||||
return redirect($attachment->path);
|
return redirect($attachment->path);
|
||||||
@@ -246,7 +246,7 @@ class AttachmentController extends Controller
|
|||||||
{
|
{
|
||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||||
$this->checkOwnablePermission('attachment-delete', $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentDelete, $attachment);
|
||||||
$this->attachmentService->deleteFile($attachment);
|
$this->attachmentService->deleteFile($attachment);
|
||||||
|
|
||||||
return response()->json(['message' => trans('entities.attachments_deleted')]);
|
return response()->json(['message' => trans('entities.attachments_deleted')]);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Uploads\Controllers;
|
|||||||
|
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Uploads\ImageResizer;
|
use BookStack\Uploads\ImageResizer;
|
||||||
use BookStack\Util\OutOfMemoryHandler;
|
use BookStack\Util\OutOfMemoryHandler;
|
||||||
@@ -57,7 +58,7 @@ class DrawioImageController extends Controller
|
|||||||
'uploaded_to' => ['required', 'integer'],
|
'uploaded_to' => ['required', 'integer'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->checkPermission('image-create-all');
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
$imageBase64Data = $request->get('image');
|
$imageBase64Data = $request->get('image');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -81,7 +82,7 @@ class DrawioImageController extends Controller
|
|||||||
return $this->jsonError(trans('errors.drawing_data_not_found'), 404);
|
return $this->jsonError(trans('errors.drawing_data_not_found'), 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($image->type !== 'drawio' || !userCan('page-view', $image->getPage())) {
|
if ($image->type !== 'drawio' || !userCan(Permission::PageView, $image->getPage())) {
|
||||||
return $this->jsonError(trans('errors.drawing_data_not_found'), 404);
|
return $this->jsonError(trans('errors.drawing_data_not_found'), 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Uploads\Controllers;
|
|||||||
|
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Uploads\ImageResizer;
|
use BookStack\Uploads\ImageResizer;
|
||||||
use BookStack\Util\OutOfMemoryHandler;
|
use BookStack\Util\OutOfMemoryHandler;
|
||||||
@@ -52,7 +53,7 @@ class GalleryImageController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('image-create-all');
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Exceptions\ImageUploadException;
|
|||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Exceptions\NotifyException;
|
use BookStack\Exceptions\NotifyException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Image;
|
use BookStack\Uploads\Image;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Uploads\ImageResizer;
|
use BookStack\Uploads\ImageResizer;
|
||||||
@@ -50,7 +51,7 @@ class ImageController extends Controller
|
|||||||
|
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkImagePermission($image);
|
$this->checkImagePermission($image);
|
||||||
$this->checkOwnablePermission('image-update', $image);
|
$this->checkOwnablePermission(Permission::ImageUpdate, $image);
|
||||||
|
|
||||||
$image = $this->imageRepo->updateImageDetails($image, $data);
|
$image = $this->imageRepo->updateImageDetails($image, $data);
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ class ImageController extends Controller
|
|||||||
|
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkImagePermission($image);
|
$this->checkImagePermission($image);
|
||||||
$this->checkOwnablePermission('image-update', $image);
|
$this->checkOwnablePermission(Permission::ImageUpdate, $image);
|
||||||
$file = $request->file('file');
|
$file = $request->file('file');
|
||||||
|
|
||||||
new OutOfMemoryHandler(function () {
|
new OutOfMemoryHandler(function () {
|
||||||
@@ -125,7 +126,7 @@ class ImageController extends Controller
|
|||||||
public function destroy(string $id)
|
public function destroy(string $id)
|
||||||
{
|
{
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkOwnablePermission('image-delete', $image);
|
$this->checkOwnablePermission(Permission::ImageDelete, $image);
|
||||||
$this->checkImagePermission($image);
|
$this->checkImagePermission($image);
|
||||||
|
|
||||||
$this->imageRepo->destroyImage($image);
|
$this->imageRepo->destroyImage($image);
|
||||||
@@ -140,7 +141,7 @@ class ImageController extends Controller
|
|||||||
{
|
{
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkImagePermission($image);
|
$this->checkImagePermission($image);
|
||||||
$this->checkOwnablePermission('image-update', $image);
|
$this->checkOwnablePermission(Permission::ImageUpdate, $image);
|
||||||
|
|
||||||
new OutOfMemoryHandler(function () {
|
new OutOfMemoryHandler(function () {
|
||||||
return $this->jsonError(trans('errors.image_thumbnail_memory_limit'));
|
return $this->jsonError(trans('errors.image_thumbnail_memory_limit'));
|
||||||
@@ -163,7 +164,7 @@ class ImageController extends Controller
|
|||||||
|
|
||||||
$relatedPage = $image->getPage();
|
$relatedPage = $image->getPage();
|
||||||
if ($relatedPage) {
|
if ($relatedPage) {
|
||||||
$this->checkOwnablePermission('page-view', $relatedPage);
|
$this->checkOwnablePermission(Permission::PageView, $relatedPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Uploads\Controllers;
|
|||||||
|
|
||||||
use BookStack\Entities\Queries\PageQueries;
|
use BookStack\Entities\Queries\PageQueries;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\Image;
|
use BookStack\Uploads\Image;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Uploads\ImageResizer;
|
use BookStack\Uploads\ImageResizer;
|
||||||
@@ -65,7 +66,7 @@ class ImageGalleryApiController extends ApiController
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('image-create-all');
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
$data = $this->validate($request, $this->rules()['create']);
|
$data = $this->validate($request, $this->rules()['create']);
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($data['uploaded_to']);
|
$page = $this->pageQueries->findVisibleByIdOrFail($data['uploaded_to']);
|
||||||
|
|
||||||
@@ -102,8 +103,8 @@ class ImageGalleryApiController extends ApiController
|
|||||||
{
|
{
|
||||||
$data = $this->validate($request, $this->rules()['update']);
|
$data = $this->validate($request, $this->rules()['update']);
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkOwnablePermission('page-view', $image->getPage());
|
$this->checkOwnablePermission(Permission::PageView, $image->getPage());
|
||||||
$this->checkOwnablePermission('image-update', $image);
|
$this->checkOwnablePermission(Permission::ImageUpdate, $image);
|
||||||
|
|
||||||
$this->imageRepo->updateImageDetails($image, $data);
|
$this->imageRepo->updateImageDetails($image, $data);
|
||||||
if (isset($data['image'])) {
|
if (isset($data['image'])) {
|
||||||
@@ -121,8 +122,8 @@ class ImageGalleryApiController extends ApiController
|
|||||||
public function delete(string $id)
|
public function delete(string $id)
|
||||||
{
|
{
|
||||||
$image = $this->imageRepo->getById($id);
|
$image = $this->imageRepo->getById($id);
|
||||||
$this->checkOwnablePermission('page-view', $image->getPage());
|
$this->checkOwnablePermission(Permission::PageView, $image->getPage());
|
||||||
$this->checkOwnablePermission('image-delete', $image);
|
$this->checkOwnablePermission(Permission::ImageDelete, $image);
|
||||||
$this->imageRepo->destroyImage($image);
|
$this->imageRepo->destroyImage($image);
|
||||||
|
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Users\Controllers;
|
namespace BookStack\Users\Controllers;
|
||||||
|
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Permissions\PermissionsRepo;
|
use BookStack\Permissions\PermissionsRepo;
|
||||||
use BookStack\Users\Models\Role;
|
use BookStack\Users\Models\Role;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -10,8 +11,6 @@ use Illuminate\Support\Facades\DB;
|
|||||||
|
|
||||||
class RoleApiController extends ApiController
|
class RoleApiController extends ApiController
|
||||||
{
|
{
|
||||||
protected PermissionsRepo $permissionsRepo;
|
|
||||||
|
|
||||||
protected array $fieldsToExpose = [
|
protected array $fieldsToExpose = [
|
||||||
'display_name', 'description', 'mfa_enforced', 'external_auth_id', 'created_at', 'updated_at',
|
'display_name', 'description', 'mfa_enforced', 'external_auth_id', 'created_at', 'updated_at',
|
||||||
];
|
];
|
||||||
@@ -35,13 +34,12 @@ class RoleApiController extends ApiController
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(PermissionsRepo $permissionsRepo)
|
public function __construct(
|
||||||
{
|
protected PermissionsRepo $permissionsRepo
|
||||||
$this->permissionsRepo = $permissionsRepo;
|
) {
|
||||||
|
|
||||||
// Checks for all endpoints in this controller
|
// Checks for all endpoints in this controller
|
||||||
$this->middleware(function ($request, $next) {
|
$this->middleware(function ($request, $next) {
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
});
|
});
|
||||||
@@ -125,9 +123,9 @@ class RoleApiController extends ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format the given role model for single-result display.
|
* Format the given role model for a single-result display.
|
||||||
*/
|
*/
|
||||||
protected function singleFormatter(Role $role)
|
protected function singleFormatter(Role $role): void
|
||||||
{
|
{
|
||||||
$role->load('users:id,name,slug');
|
$role->load('users:id,name,slug');
|
||||||
$role->unsetRelation('permissions');
|
$role->unsetRelation('permissions');
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Users\Controllers;
|
|||||||
|
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Permissions\PermissionsRepo;
|
use BookStack\Permissions\PermissionsRepo;
|
||||||
use BookStack\Users\Models\Role;
|
use BookStack\Users\Models\Role;
|
||||||
use BookStack\Users\Queries\RolesAllPaginatedAndSorted;
|
use BookStack\Users\Queries\RolesAllPaginatedAndSorted;
|
||||||
@@ -23,7 +24,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
|
|
||||||
$listOptions = SimpleListOptions::fromRequest($request, 'roles')->withSortOptions([
|
$listOptions = SimpleListOptions::fromRequest($request, 'roles')->withSortOptions([
|
||||||
'display_name' => trans('common.sort_name'),
|
'display_name' => trans('common.sort_name'),
|
||||||
@@ -49,7 +50,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
|
|
||||||
/** @var ?Role $role */
|
/** @var ?Role $role */
|
||||||
$role = null;
|
$role = null;
|
||||||
@@ -71,7 +72,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
$data = $this->validate($request, [
|
$data = $this->validate($request, [
|
||||||
'display_name' => ['required', 'min:3', 'max:180'],
|
'display_name' => ['required', 'min:3', 'max:180'],
|
||||||
'description' => ['max:180'],
|
'description' => ['max:180'],
|
||||||
@@ -92,7 +93,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
$role = $this->permissionsRepo->getRoleById($id);
|
$role = $this->permissionsRepo->getRoleById($id);
|
||||||
|
|
||||||
$this->setPageTitle(trans('settings.role_edit'));
|
$this->setPageTitle(trans('settings.role_edit'));
|
||||||
@@ -105,7 +106,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(Request $request, string $id)
|
public function update(Request $request, string $id)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
$data = $this->validate($request, [
|
$data = $this->validate($request, [
|
||||||
'display_name' => ['required', 'min:3', 'max:180'],
|
'display_name' => ['required', 'min:3', 'max:180'],
|
||||||
'description' => ['max:180'],
|
'description' => ['max:180'],
|
||||||
@@ -127,7 +128,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function showDelete(string $id)
|
public function showDelete(string $id)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
$role = $this->permissionsRepo->getRoleById($id);
|
$role = $this->permissionsRepo->getRoleById($id);
|
||||||
$roles = $this->permissionsRepo->getAllRolesExcept($role);
|
$roles = $this->permissionsRepo->getAllRolesExcept($role);
|
||||||
$blankRole = $role->newInstance(['display_name' => trans('settings.role_delete_no_migration')]);
|
$blankRole = $role->newInstance(['display_name' => trans('settings.role_delete_no_migration')]);
|
||||||
@@ -146,7 +147,7 @@ class RoleController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function delete(Request $request, string $id)
|
public function delete(Request $request, string $id)
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-roles-manage');
|
$this->checkPermission(Permission::UserRolesManage);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$migrateRoleId = intval($request->get('migrate_role_id') ?: "0");
|
$migrateRoleId = intval($request->get('migrate_role_id') ?: "0");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Users\Controllers;
|
|||||||
|
|
||||||
use BookStack\Access\SocialDriverManager;
|
use BookStack\Access\SocialDriverManager;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Permissions\PermissionApplicator;
|
use BookStack\Permissions\PermissionApplicator;
|
||||||
use BookStack\Settings\UserNotificationPreferences;
|
use BookStack\Settings\UserNotificationPreferences;
|
||||||
use BookStack\Settings\UserShortcutMap;
|
use BookStack\Settings\UserShortcutMap;
|
||||||
@@ -62,9 +63,9 @@ class UserAccountController extends Controller
|
|||||||
'profile_image' => array_merge(['nullable'], $this->getImageValidationRules()),
|
'profile_image' => array_merge(['nullable'], $this->getImageValidationRules()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->userRepo->update($user, $validated, userCan('users-manage'));
|
$this->userRepo->update($user, $validated, userCan(Permission::UsersManage));
|
||||||
|
|
||||||
// Save profile image if in request
|
// Save the profile image if in request
|
||||||
if ($request->hasFile('profile_image')) {
|
if ($request->hasFile('profile_image')) {
|
||||||
$imageUpload = $request->file('profile_image');
|
$imageUpload = $request->file('profile_image');
|
||||||
$imageRepo->destroyImage($user->avatar);
|
$imageRepo->destroyImage($user->avatar);
|
||||||
@@ -73,7 +74,7 @@ class UserAccountController extends Controller
|
|||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the profile image if reset option is in request
|
// Delete the profile image if the reset option is in request
|
||||||
if ($request->has('profile_image_reset')) {
|
if ($request->has('profile_image_reset')) {
|
||||||
$imageRepo->destroyImage($user->avatar);
|
$imageRepo->destroyImage($user->avatar);
|
||||||
$user->image_id = 0;
|
$user->image_id = 0;
|
||||||
@@ -122,7 +123,7 @@ class UserAccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function showNotifications(PermissionApplicator $permissions)
|
public function showNotifications(PermissionApplicator $permissions)
|
||||||
{
|
{
|
||||||
$this->checkPermission('receive-notifications');
|
$this->checkPermission(Permission::ReceiveNotifications);
|
||||||
|
|
||||||
$preferences = (new UserNotificationPreferences(user()));
|
$preferences = (new UserNotificationPreferences(user()));
|
||||||
|
|
||||||
@@ -145,7 +146,7 @@ class UserAccountController extends Controller
|
|||||||
public function updateNotifications(Request $request)
|
public function updateNotifications(Request $request)
|
||||||
{
|
{
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
$this->checkPermission('receive-notifications');
|
$this->checkPermission(Permission::ReceiveNotifications);
|
||||||
$data = $this->validate($request, [
|
$data = $this->validate($request, [
|
||||||
'preferences' => ['required', 'array'],
|
'preferences' => ['required', 'array'],
|
||||||
'preferences.*' => ['required', 'string'],
|
'preferences.*' => ['required', 'string'],
|
||||||
@@ -218,7 +219,7 @@ class UserAccountController extends Controller
|
|||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
|
|
||||||
$requestNewOwnerId = intval($request->get('new_owner_id')) ?: null;
|
$requestNewOwnerId = intval($request->get('new_owner_id')) ?: null;
|
||||||
$newOwnerId = userCan('users-manage') ? $requestNewOwnerId : null;
|
$newOwnerId = userCan(Permission::UsersManage) ? $requestNewOwnerId : null;
|
||||||
|
|
||||||
$this->userRepo->destroy(user(), $newOwnerId);
|
$this->userRepo->destroy(user(), $newOwnerId);
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ namespace BookStack\Users\Controllers;
|
|||||||
|
|
||||||
use BookStack\Exceptions\UserUpdateException;
|
use BookStack\Exceptions\UserUpdateException;
|
||||||
use BookStack\Http\ApiController;
|
use BookStack\Http\ApiController;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use BookStack\Users\UserRepo;
|
use BookStack\Users\UserRepo;
|
||||||
use Closure;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Validation\Rules\Password;
|
use Illuminate\Validation\Rules\Password;
|
||||||
@@ -26,7 +26,7 @@ class UserApiController extends ApiController
|
|||||||
|
|
||||||
// Checks for all endpoints in this controller
|
// Checks for all endpoints in this controller
|
||||||
$this->middleware(function ($request, $next) {
|
$this->middleware(function ($request, $next) {
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
@@ -125,7 +125,7 @@ class UserApiController extends ApiController
|
|||||||
{
|
{
|
||||||
$data = $this->validate($request, $this->rules($id)['update']);
|
$data = $this->validate($request, $this->rules($id)['update']);
|
||||||
$user = $this->userRepo->getById($id);
|
$user = $this->userRepo->getById($id);
|
||||||
$this->userRepo->update($user, $data, userCan('users-manage'));
|
$this->userRepo->update($user, $data, userCan(Permission::UsersManage));
|
||||||
$this->singleFormatter($user);
|
$this->singleFormatter($user);
|
||||||
|
|
||||||
return response()->json($user);
|
return response()->json($user);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use BookStack\Access\UserInviteException;
|
|||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Exceptions\UserUpdateException;
|
use BookStack\Exceptions\UserUpdateException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Uploads\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Users\Models\Role;
|
use BookStack\Users\Models\Role;
|
||||||
use BookStack\Users\Queries\UsersAllPaginatedAndSorted;
|
use BookStack\Users\Queries\UsersAllPaginatedAndSorted;
|
||||||
@@ -32,7 +33,7 @@ class UserController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$listOptions = SimpleListOptions::fromRequest($request, 'users')->withSortOptions([
|
$listOptions = SimpleListOptions::fromRequest($request, 'users')->withSortOptions([
|
||||||
'name' => trans('common.sort_name'),
|
'name' => trans('common.sort_name'),
|
||||||
@@ -58,7 +59,7 @@ class UserController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
$authMethod = config('auth.method');
|
$authMethod = config('auth.method');
|
||||||
$roles = Role::query()->orderBy('display_name', 'asc')->get();
|
$roles = Role::query()->orderBy('display_name', 'asc')->get();
|
||||||
$this->setPageTitle(trans('settings.users_add_new'));
|
$this->setPageTitle(trans('settings.users_add_new'));
|
||||||
@@ -73,7 +74,7 @@ class UserController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$authMethod = config('auth.method');
|
$authMethod = config('auth.method');
|
||||||
$sendInvite = ($request->get('send_invite', 'false') === 'true');
|
$sendInvite = ($request->get('send_invite', 'false') === 'true');
|
||||||
@@ -111,7 +112,7 @@ class UserController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(int $id, SocialDriverManager $socialDriverManager)
|
public function edit(int $id, SocialDriverManager $socialDriverManager)
|
||||||
{
|
{
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$user = $this->userRepo->getById($id);
|
$user = $this->userRepo->getById($id);
|
||||||
$user->load(['apiTokens', 'mfaValues']);
|
$user->load(['apiTokens', 'mfaValues']);
|
||||||
@@ -141,7 +142,7 @@ class UserController extends Controller
|
|||||||
public function update(Request $request, int $id)
|
public function update(Request $request, int $id)
|
||||||
{
|
{
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'name' => ['min:1', 'max:100'],
|
'name' => ['min:1', 'max:100'],
|
||||||
@@ -182,7 +183,7 @@ class UserController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function delete(int $id)
|
public function delete(int $id)
|
||||||
{
|
{
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$user = $this->userRepo->getById($id);
|
$user = $this->userRepo->getById($id);
|
||||||
$this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
|
$this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
|
||||||
@@ -198,7 +199,7 @@ class UserController extends Controller
|
|||||||
public function destroy(Request $request, int $id)
|
public function destroy(Request $request, int $id)
|
||||||
{
|
{
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
$user = $this->userRepo->getById($id);
|
$user = $this->userRepo->getById($id);
|
||||||
$newOwnerId = intval($request->get('new_owner_id')) ?: null;
|
$newOwnerId = intval($request->get('new_owner_id')) ?: null;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Users\Controllers;
|
namespace BookStack\Users\Controllers;
|
||||||
|
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -15,9 +16,9 @@ class UserSearchController extends Controller
|
|||||||
public function forSelect(Request $request)
|
public function forSelect(Request $request)
|
||||||
{
|
{
|
||||||
$hasPermission = !user()->isGuest() && (
|
$hasPermission = !user()->isGuest() && (
|
||||||
userCan('users-manage')
|
userCan(Permission::UsersManage)
|
||||||
|| userCan('restrictions-manage-own')
|
|| userCan(Permission::RestrictionsManageOwn)
|
||||||
|| userCan('restrictions-manage-all')
|
|| userCan(Permission::RestrictionsManageAll)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$hasPermission) {
|
if (!$hasPermission) {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ class Role extends Model implements Loggable
|
|||||||
*/
|
*/
|
||||||
public function permissions(): BelongsToMany
|
public function permissions(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(RolePermission::class, 'permission_role', 'role_id', 'permission_id');
|
return $this->belongsToMany(RolePermission::class, 'permission_role', 'role_id', 'permission_id')
|
||||||
|
->select(['id', 'name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use BookStack\Api\ApiToken;
|
|||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\App\SluggableInterface;
|
use BookStack\App\SluggableInterface;
|
||||||
use BookStack\Entities\Tools\SlugGenerator;
|
use BookStack\Entities\Tools\SlugGenerator;
|
||||||
|
use BookStack\Permissions\Permission;
|
||||||
use BookStack\Translation\LocaleDefinition;
|
use BookStack\Translation\LocaleDefinition;
|
||||||
use BookStack\Translation\LocaleManager;
|
use BookStack\Translation\LocaleManager;
|
||||||
use BookStack\Uploads\Image;
|
use BookStack\Uploads\Image;
|
||||||
@@ -26,7 +27,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
@@ -156,8 +156,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
/**
|
/**
|
||||||
* Check if the user has a particular permission.
|
* Check if the user has a particular permission.
|
||||||
*/
|
*/
|
||||||
public function can(string $permissionName): bool
|
public function can(string|Permission $permission): bool
|
||||||
{
|
{
|
||||||
|
$permissionName = is_string($permission) ? $permission : $permission->value;
|
||||||
return $this->permissions()->contains($permissionName);
|
return $this->permissions()->contains($permissionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,9 +182,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear any cached permissions on this instance.
|
* Clear any cached permissions in this instance.
|
||||||
*/
|
*/
|
||||||
public function clearPermissionCache()
|
public function clearPermissionCache(): void
|
||||||
{
|
{
|
||||||
$this->permissions = null;
|
$this->permissions = null;
|
||||||
}
|
}
|
||||||
@@ -191,7 +192,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
/**
|
/**
|
||||||
* Attach a role to this user.
|
* Attach a role to this user.
|
||||||
*/
|
*/
|
||||||
public function attachRole(Role $role)
|
public function attachRole(Role $role): void
|
||||||
{
|
{
|
||||||
$this->roles()->attach($role->id);
|
$this->roles()->attach($role->id);
|
||||||
$this->unsetRelation('roles');
|
$this->unsetRelation('roles');
|
||||||
@@ -207,15 +208,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the user has a social account,
|
* Check if the user has a social account,
|
||||||
* If a driver is passed it checks for that single account type.
|
* If a driver is passed, it checks for that single account type.
|
||||||
*
|
|
||||||
* @param bool|string $socialDriver
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function hasSocialAccount($socialDriver = false)
|
public function hasSocialAccount(string $socialDriver = ''): bool
|
||||||
{
|
{
|
||||||
if ($socialDriver === false) {
|
if (empty($socialDriver)) {
|
||||||
return $this->socialAccounts()->count() > 0;
|
return $this->socialAccounts()->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ return new class extends Migration
|
|||||||
Schema::table('comments', function (Blueprint $table) {
|
Schema::table('comments', function (Blueprint $table) {
|
||||||
$table->dropColumn('text');
|
$table->dropColumn('text');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('role_permissions', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('display_name');
|
||||||
|
$table->dropColumn('description');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,5 +29,10 @@ return new class extends Migration
|
|||||||
Schema::table('comments', function (Blueprint $table) {
|
Schema::table('comments', function (Blueprint $table) {
|
||||||
$table->longText('text')->nullable();
|
$table->longText('text')->nullable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('role_permissions', function (Blueprint $table) {
|
||||||
|
$table->string('display_name')->nullable();
|
||||||
|
$table->string('description')->nullable();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
title="{{ trans('entities.attachments_insert_link') }}"
|
title="{{ trans('entities.attachments_insert_link') }}"
|
||||||
class="drag-card-action text-center text-link">@icon('link')</button>
|
class="drag-card-action text-center text-link">@icon('link')</button>
|
||||||
@if(userCan('attachment-update', $attachment))
|
@if(userCan(\BookStack\Permissions\Permission::AttachmentUpdate, $attachment))
|
||||||
<button component="event-emit-select"
|
<button component="event-emit-select"
|
||||||
option:event-emit-select:name="edit"
|
option:event-emit-select:name="edit"
|
||||||
option:event-emit-select:id="{{ $attachment->id }}"
|
option:event-emit-select:id="{{ $attachment->id }}"
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
title="{{ trans('common.edit') }}"
|
title="{{ trans('common.edit') }}"
|
||||||
class="drag-card-action text-center text-link">@icon('edit')</button>
|
class="drag-card-action text-center text-link">@icon('edit')</button>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('attachment-delete', $attachment))
|
@if(userCan(\BookStack\Permissions\Permission::AttachmentDelete, $attachment))
|
||||||
<div component="dropdown" class="flex-fill relative">
|
<div component="dropdown" class="flex-fill relative">
|
||||||
<button refs="dropdown@toggle"
|
<button refs="dropdown@toggle"
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
||||||
@if(userCan('book-delete', $book) && userCan('book-create-all') && userCan('bookshelf-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookDelete, $book) && userCan(\BookStack\Permissions\Permission::BookCreateAll) && userCan(\BookStack\Permissions\Permission::BookshelfCreateAll))
|
||||||
@include('books.parts.convert-to-shelf', ['book' => $book])
|
@include('books.parts.convert-to-shelf', ['book' => $book])
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<div class="actions mb-xl">
|
<div class="actions mb-xl">
|
||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
@if(userCan('book-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll))
|
||||||
<a href="{{ url("/create-book") }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ url("/create-book") }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.books_create') }}</span>
|
<span>{{ trans('entities.books_create') }}</span>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<span>{{ trans('entities.tags_view_tags') }}</span>
|
<span>{{ trans('entities.tags_view_tags') }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@if(userCan('content-import'))
|
@if(userCan(\BookStack\Permissions\Permission::ContentImport))
|
||||||
<a href="{{ url('/import') }}" class="icon-list-item">
|
<a href="{{ url('/import') }}" class="icon-list-item">
|
||||||
<span>@icon('upload')</span>
|
<span>@icon('upload')</span>
|
||||||
<span>{{ trans('entities.import') }}</span>
|
<span>{{ trans('entities.import') }}</span>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p class="text-muted">{{ trans('entities.books_empty') }}</p>
|
<p class="text-muted">{{ trans('entities.books_empty') }}</p>
|
||||||
@if(userCan('book-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll))
|
||||||
<div class="icon-list block inline">
|
<div class="icon-list block inline">
|
||||||
<a href="{{ url("/create-book") }}"
|
<a href="{{ url("/create-book") }}"
|
||||||
class="icon-list-item text-book">
|
class="icon-list-item text-book">
|
||||||
|
|||||||
@@ -43,13 +43,13 @@
|
|||||||
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.books_empty_contents') }}</p>
|
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.books_empty_contents') }}</p>
|
||||||
|
|
||||||
<div class="icon-list block inline">
|
<div class="icon-list block inline">
|
||||||
@if(userCan('page-create', $book))
|
@if(userCan(\BookStack\Permissions\Permission::PageCreate, $book))
|
||||||
<a href="{{ $book->getUrl('/create-page') }}" class="icon-list-item text-page">
|
<a href="{{ $book->getUrl('/create-page') }}" class="icon-list-item text-page">
|
||||||
<span class="icon">@icon('page')</span>
|
<span class="icon">@icon('page')</span>
|
||||||
<span>{{ trans('entities.books_empty_create_page') }}</span>
|
<span>{{ trans('entities.books_empty_create_page') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('chapter-create', $book))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterCreate, $book))
|
||||||
<a href="{{ $book->getUrl('/create-chapter') }}" class="icon-list-item text-chapter">
|
<a href="{{ $book->getUrl('/create-chapter') }}" class="icon-list-item text-chapter">
|
||||||
<span class="icon">@icon('chapter')</span>
|
<span class="icon">@icon('chapter')</span>
|
||||||
<span>{{ trans('entities.books_empty_add_chapter') }}</span>
|
<span>{{ trans('entities.books_empty_add_chapter') }}</span>
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
@include('entities.meta', ['entity' => $book, 'watchOptions' => $watchOptions])
|
@include('entities.meta', ['entity' => $book, 'watchOptions' => $watchOptions])
|
||||||
@if($book->hasPermissions())
|
@if($book->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $book))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $book))
|
||||||
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.books_permissions_active') }}</div>
|
<div>{{ trans('entities.books_permissions_active') }}</div>
|
||||||
@@ -93,13 +93,13 @@
|
|||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
|
|
||||||
@if(userCan('page-create', $book))
|
@if(userCan(\BookStack\Permissions\Permission::PageCreate, $book))
|
||||||
<a href="{{ $book->getUrl('/create-page') }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ $book->getUrl('/create-page') }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.pages_new') }}</span>
|
<span>{{ trans('entities.pages_new') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('chapter-create', $book))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterCreate, $book))
|
||||||
<a href="{{ $book->getUrl('/create-chapter') }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ $book->getUrl('/create-chapter') }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.chapters_new') }}</span>
|
<span>{{ trans('entities.chapters_new') }}</span>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
<hr class="primary-background">
|
<hr class="primary-background">
|
||||||
|
|
||||||
@if(userCan('book-update', $book))
|
@if(userCan(\BookStack\Permissions\Permission::BookUpdate, $book))
|
||||||
<a href="{{ $book->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
<a href="{{ $book->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
||||||
<span>@icon('edit')</span>
|
<span>@icon('edit')</span>
|
||||||
<span>{{ trans('common.edit') }}</span>
|
<span>{{ trans('common.edit') }}</span>
|
||||||
@@ -118,19 +118,19 @@
|
|||||||
<span>{{ trans('common.sort') }}</span>
|
<span>{{ trans('common.sort') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('book-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll))
|
||||||
<a href="{{ $book->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
<a href="{{ $book->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
||||||
<span>@icon('copy')</span>
|
<span>@icon('copy')</span>
|
||||||
<span>{{ trans('common.copy') }}</span>
|
<span>{{ trans('common.copy') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('restrictions-manage', $book))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $book))
|
||||||
<a href="{{ $book->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
<a href="{{ $book->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
||||||
<span>@icon('lock')</span>
|
<span>@icon('lock')</span>
|
||||||
<span>{{ trans('entities.permissions') }}</span>
|
<span>{{ trans('entities.permissions') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('book-delete', $book))
|
@if(userCan(\BookStack\Permissions\Permission::BookDelete, $book))
|
||||||
<a href="{{ $book->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
<a href="{{ $book->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
||||||
<span>@icon('delete')</span>
|
<span>@icon('delete')</span>
|
||||||
<span>{{ trans('common.delete') }}</span>
|
<span>{{ trans('common.delete') }}</span>
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
@if(!user()->isGuest())
|
@if(!user()->isGuest())
|
||||||
@include('entities.favourite-action', ['entity' => $book])
|
@include('entities.favourite-action', ['entity' => $book])
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('content-export'))
|
@if(userCan(\BookStack\Permissions\Permission::ContentExport))
|
||||||
@include('entities.export-menu', ['entity' => $book])
|
@include('entities.export-menu', ['entity' => $book])
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@if(userCan('chapter-delete', $chapter) && userCan('book-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterDelete, $chapter) && userCan(\BookStack\Permissions\Permission::BookCreateAll))
|
||||||
@include('chapters.parts.convert-to-book')
|
@include('chapters.parts.convert-to-book')
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,13 @@
|
|||||||
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.chapters_empty') }}</p>
|
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.chapters_empty') }}</p>
|
||||||
|
|
||||||
<div class="icon-list block inline">
|
<div class="icon-list block inline">
|
||||||
@if(userCan('page-create', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::PageCreate, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/create-page') }}" class="icon-list-item text-page">
|
<a href="{{ $chapter->getUrl('/create-page') }}" class="icon-list-item text-page">
|
||||||
<span class="icon">@icon('page')</span>
|
<span class="icon">@icon('page')</span>
|
||||||
<span>{{ trans('entities.books_empty_create_page') }}</span>
|
<span>{{ trans('entities.books_empty_create_page') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('book-update', $book))
|
@if(userCan(\BookStack\Permissions\Permission::BookUpdate, $book))
|
||||||
<a href="{{ $book->getUrl('/sort') }}" class="icon-list-item text-book">
|
<a href="{{ $book->getUrl('/sort') }}" class="icon-list-item text-book">
|
||||||
<span class="icon">@icon('book')</span>
|
<span class="icon">@icon('book')</span>
|
||||||
<span>{{ trans('entities.books_empty_sort_current_book') }}</span>
|
<span>{{ trans('entities.books_empty_sort_current_book') }}</span>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
@if($book->hasPermissions())
|
@if($book->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $book))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $book))
|
||||||
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.books_permissions_active') }}</div>
|
<div>{{ trans('entities.books_permissions_active') }}</div>
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
@if($chapter->hasPermissions())
|
@if($chapter->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $chapter->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.chapters_permissions_active') }}</div>
|
<div>{{ trans('entities.chapters_permissions_active') }}</div>
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
|
|
||||||
@if(userCan('page-create', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::PageCreate, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/create-page') }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/create-page') }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.pages_new') }}</span>
|
<span>{{ trans('entities.pages_new') }}</span>
|
||||||
@@ -116,38 +116,38 @@
|
|||||||
|
|
||||||
<hr class="primary-background"/>
|
<hr class="primary-background"/>
|
||||||
|
|
||||||
@if(userCan('chapter-update', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterUpdate, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
||||||
<span>@icon('edit')</span>
|
<span>@icon('edit')</span>
|
||||||
<span>{{ trans('common.edit') }}</span>
|
<span>{{ trans('common.edit') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCanOnAny('create', \BookStack\Entities\Models\Book::class) || userCan('chapter-create-all') || userCan('chapter-create-own'))
|
@if(userCanOnAny(\BookStack\Permissions\Permission::Create, \BookStack\Entities\Models\Book::class) || userCan(\BookStack\Permissions\Permission::ChapterCreateAll) || userCan(\BookStack\Permissions\Permission::ChapterCreateOwn))
|
||||||
<a href="{{ $chapter->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
||||||
<span>@icon('copy')</span>
|
<span>@icon('copy')</span>
|
||||||
<span>{{ trans('common.copy') }}</span>
|
<span>{{ trans('common.copy') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('chapter-update', $chapter) && userCan('chapter-delete', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterUpdate, $chapter) && userCan(\BookStack\Permissions\Permission::ChapterDelete, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/move') }}" data-shortcut="move" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/move') }}" data-shortcut="move" class="icon-list-item">
|
||||||
<span>@icon('folder')</span>
|
<span>@icon('folder')</span>
|
||||||
<span>{{ trans('common.move') }}</span>
|
<span>{{ trans('common.move') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('restrictions-manage', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
||||||
<span>@icon('lock')</span>
|
<span>@icon('lock')</span>
|
||||||
<span>{{ trans('entities.permissions') }}</span>
|
<span>{{ trans('entities.permissions') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('chapter-delete', $chapter))
|
@if(userCan(\BookStack\Permissions\Permission::ChapterDelete, $chapter))
|
||||||
<a href="{{ $chapter->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
<a href="{{ $chapter->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
||||||
<span>@icon('delete')</span>
|
<span>@icon('delete')</span>
|
||||||
<span>{{ trans('common.delete') }}</span>
|
<span>{{ trans('common.delete') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($chapter->book && userCan('book-update', $chapter->book))
|
@if($chapter->book && userCan(\BookStack\Permissions\Permission::BookUpdate, $chapter->book))
|
||||||
<hr class="primary-background"/>
|
<hr class="primary-background"/>
|
||||||
<a href="{{ $chapter->book->getUrl('/sort') }}" data-shortcut="sort" class="icon-list-item">
|
<a href="{{ $chapter->book->getUrl('/sort') }}" data-shortcut="sort" class="icon-list-item">
|
||||||
<span>@icon('sort')</span>
|
<span>@icon('sort')</span>
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
@if(!user()->isGuest())
|
@if(!user()->isGuest())
|
||||||
@include('entities.favourite-action', ['entity' => $chapter])
|
@include('entities.favourite-action', ['entity' => $chapter])
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('content-export'))
|
@if(userCan(\BookStack\Permissions\Permission::ContentExport))
|
||||||
@include('entities.export-menu', ['entity' => $chapter])
|
@include('entities.export-menu', ['entity' => $chapter])
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,23 +33,23 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="right-meta flex-container-row justify-flex-end items-center px-s">
|
<div class="right-meta flex-container-row justify-flex-end items-center px-s">
|
||||||
@if(!$readOnly && (userCan('comment-create-all') || userCan('comment-update', $comment) || userCan('comment-delete', $comment)))
|
@if(!$readOnly && (userCan(\BookStack\Permissions\Permission::CommentCreateAll) || userCan(\BookStack\Permissions\Permission::CommentUpdate, $comment) || userCan(\BookStack\Permissions\Permission::CommentDelete, $comment)))
|
||||||
<div class="actions mr-s">
|
<div class="actions mr-s">
|
||||||
@if(userCan('comment-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::CommentCreateAll))
|
||||||
<button refs="page-comment@reply-button" type="button"
|
<button refs="page-comment@reply-button" type="button"
|
||||||
class="text-button text-muted hover-underline text-small p-xs">@icon('reply') {{ trans('common.reply') }}</button>
|
class="text-button text-muted hover-underline text-small p-xs">@icon('reply') {{ trans('common.reply') }}</button>
|
||||||
@endif
|
@endif
|
||||||
@if(!$comment->parent_id && (userCan('comment-update', $comment) || userCan('comment-delete', $comment)))
|
@if(!$comment->parent_id && (userCan(\BookStack\Permissions\Permission::CommentUpdate, $comment) || userCan(\BookStack\Permissions\Permission::CommentDelete, $comment)))
|
||||||
<button refs="page-comment@archive-button"
|
<button refs="page-comment@archive-button"
|
||||||
type="button"
|
type="button"
|
||||||
data-is-archived="{{ $comment->archived ? 'true' : 'false' }}"
|
data-is-archived="{{ $comment->archived ? 'true' : 'false' }}"
|
||||||
class="text-button text-muted hover-underline text-small p-xs">@icon('archive') {{ trans('common.' . ($comment->archived ? 'unarchive' : 'archive')) }}</button>
|
class="text-button text-muted hover-underline text-small p-xs">@icon('archive') {{ trans('common.' . ($comment->archived ? 'unarchive' : 'archive')) }}</button>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('comment-update', $comment))
|
@if(userCan(\BookStack\Permissions\Permission::CommentUpdate, $comment))
|
||||||
<button refs="page-comment@edit-button" type="button"
|
<button refs="page-comment@edit-button" type="button"
|
||||||
class="text-button text-muted hover-underline text-small p-xs">@icon('edit') {{ trans('common.edit') }}</button>
|
class="text-button text-muted hover-underline text-small p-xs">@icon('edit') {{ trans('common.edit') }}</button>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('comment-delete', $comment))
|
@if(userCan(\BookStack\Permissions\Permission::CommentDelete, $comment))
|
||||||
<div component="dropdown" class="dropdown-container">
|
<div component="dropdown" class="dropdown-container">
|
||||||
<button type="button" refs="dropdown@toggle" aria-haspopup="true" aria-expanded="false"
|
<button type="button" refs="dropdown@toggle" aria-haspopup="true" aria-expanded="false"
|
||||||
class="text-button text-muted hover-underline text-small p-xs">@icon('delete') {{ trans('common.delete') }}</button>
|
class="text-button text-muted hover-underline text-small p-xs">@icon('delete') {{ trans('common.delete') }}</button>
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
{!! $commentHtml !!}
|
{!! $commentHtml !!}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(!$readOnly && userCan('comment-update', $comment))
|
@if(!$readOnly && userCan(\BookStack\Permissions\Permission::CommentUpdate, $comment))
|
||||||
<form novalidate refs="page-comment@form" hidden class="content pt-s px-s block">
|
<form novalidate refs="page-comment@form" hidden class="content pt-s px-s block">
|
||||||
<div class="form-group description-input">
|
<div class="form-group description-input">
|
||||||
<textarea refs="page-comment@input" name="html" rows="3"
|
<textarea refs="page-comment@input" name="html" rows="3"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
refs="page-comments@archived-tab"
|
refs="page-comments@archived-tab"
|
||||||
aria-selected="false">{{ trans_choice('entities.comment_archived_count', count($commentTree->getArchived())) }}</button>
|
aria-selected="false">{{ trans_choice('entities.comment_archived_count', count($commentTree->getArchived())) }}</button>
|
||||||
</div>
|
</div>
|
||||||
@if ($commentTree->empty() && userCan('comment-create-all'))
|
@if ($commentTree->empty() && userCan(\BookStack\Permissions\Permission::CommentCreateAll))
|
||||||
<div refs="page-comments@add-button-container" class="ml-m flex-container-row" >
|
<div refs="page-comments@add-button-container" class="ml-m flex-container-row" >
|
||||||
<button type="button"
|
<button type="button"
|
||||||
refs="page-comments@add-comment-button"
|
refs="page-comments@add-comment-button"
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
<p class="text-center text-muted italic empty-state">{{ trans('entities.comment_none') }}</p>
|
<p class="text-center text-muted italic empty-state">{{ trans('entities.comment_none') }}</p>
|
||||||
|
|
||||||
@if(userCan('comment-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::CommentCreateAll))
|
||||||
@include('comments.create')
|
@include('comments.create')
|
||||||
@if (!$commentTree->empty())
|
@if (!$commentTree->empty())
|
||||||
<div refs="page-comments@addButtonContainer" class="ml-m flex-container-row">
|
<div refs="page-comments@addButtonContainer" class="ml-m flex-container-row">
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<p class="text-center text-muted italic empty-state">{{ trans('entities.comment_none') }}</p>
|
<p class="text-center text-muted italic empty-state">{{ trans('entities.comment_none') }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(userCan('comment-create-all') || $commentTree->canUpdateAny())
|
@if(userCan(\BookStack\Permissions\Permission::CommentCreateAll) || $commentTree->canUpdateAny())
|
||||||
@push('body-end')
|
@push('body-end')
|
||||||
@include('form.editor-translations')
|
@include('form.editor-translations')
|
||||||
@include('entities.selector-popup')
|
@include('entities.selector-popup')
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<h5>{{ trans('entities.books_navigation') }}</h5>
|
<h5>{{ trans('entities.books_navigation') }}</h5>
|
||||||
|
|
||||||
<ul class="sidebar-page-list mt-xs menu entity-list">
|
<ul class="sidebar-page-list mt-xs menu entity-list">
|
||||||
@if (userCan('view', $book))
|
@if (userCan(\BookStack\Permissions\Permission::BookView, $book))
|
||||||
<li class="list-item-book book">
|
<li class="list-item-book book">
|
||||||
@include('entities.list-item-basic', ['entity' => $book, 'classes' => ($current->matches($book)? 'selected' : '')])
|
@include('entities.list-item-basic', ['entity' => $book, 'classes' => ($current->matches($book)? 'selected' : '')])
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<span>@icon($crumb['icon'])</span>
|
<span>@icon($crumb['icon'])</span>
|
||||||
<span>{{ $crumb['text'] }}</span>
|
<span>{{ $crumb['text'] }}</span>
|
||||||
</a>
|
</a>
|
||||||
@elseif($isEntity && userCan('view', $crumb))
|
@elseif($isEntity && userCan(\BookStack\Permissions\Permission::View, $crumb))
|
||||||
@if($breadcrumbCount > 0)
|
@if($breadcrumbCount > 0)
|
||||||
@include('entities.breadcrumb-listing', ['entity' => $crumb])
|
@include('entities.breadcrumb-listing', ['entity' => $crumb])
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="actions mb-xl">
|
<div class="actions mb-xl">
|
||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
@if(user()->can('book-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll))
|
||||||
<a href="{{ url("/create-book") }}" class="icon-list-item">
|
<a href="{{ url("/create-book") }}" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.books_create') }}</span>
|
<span>{{ trans('entities.books_create') }}</span>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="actions mb-xl">
|
<div class="actions mb-xl">
|
||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
@if(user()->can('bookshelf-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfCreateAll))
|
||||||
<a href="{{ url("/create-shelf") }}" class="icon-list-item">
|
<a href="{{ url("/create-shelf") }}" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.shelves_new_action') }}</span>
|
<span>{{ trans('entities.shelves_new_action') }}</span>
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
@if (user()->hasAppAccess())
|
@if (user()->hasAppAccess())
|
||||||
<a class="hide-over-l" href="{{ url('/search') }}">@icon('search'){{ trans('common.search') }}</a>
|
<a class="hide-over-l" href="{{ url('/search') }}">@icon('search'){{ trans('common.search') }}</a>
|
||||||
@if(userCanOnAny('view', \BookStack\Entities\Models\Bookshelf::class) || userCan('bookshelf-view-all') || userCan('bookshelf-view-own'))
|
@if(userCanOnAny(\BookStack\Permissions\Permission::View, \BookStack\Entities\Models\Bookshelf::class) || userCan(\BookStack\Permissions\Permission::BookshelfViewAll) || userCan(\BookStack\Permissions\Permission::BookshelfViewOwn))
|
||||||
<a href="{{ url('/shelves') }}"
|
<a href="{{ url('/shelves') }}"
|
||||||
data-shortcut="shelves_view">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
|
data-shortcut="shelves_view">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
|
||||||
@endif
|
@endif
|
||||||
<a href="{{ url('/books') }}" data-shortcut="books_view">@icon('books'){{ trans('entities.books') }}</a>
|
<a href="{{ url('/books') }}" data-shortcut="books_view">@icon('books'){{ trans('entities.books') }}</a>
|
||||||
@if(!user()->isGuest() && userCan('settings-manage'))
|
@if(!user()->isGuest() && userCan(\BookStack\Permissions\Permission::SettingsManage))
|
||||||
<a href="{{ url('/settings') }}"
|
<a href="{{ url('/settings') }}"
|
||||||
data-shortcut="settings_view">@icon('settings'){{ trans('settings.settings') }}</a>
|
data-shortcut="settings_view">@icon('settings'){{ trans('settings.settings') }}</a>
|
||||||
@endif
|
@endif
|
||||||
@if(!user()->isGuest() && userCan('users-manage') && !userCan('settings-manage'))
|
@if(!user()->isGuest() && userCan(\BookStack\Permissions\Permission::UsersManage) && !userCan(\BookStack\Permissions\Permission::SettingsManage))
|
||||||
<a href="{{ url('/settings/users') }}"
|
<a href="{{ url('/settings/users') }}"
|
||||||
data-shortcut="settings_view">@icon('users'){{ trans('settings.users') }}</a>
|
data-shortcut="settings_view">@icon('users'){{ trans('settings.users') }}</a>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<div>{{ trans('entities.pages_edit_delete_draft') }}</div>
|
<div>{{ trans('entities.pages_edit_delete_draft') }}</div>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@if(userCan('editor-change'))
|
@if(userCan(\BookStack\Permissions\Permission::EditorChange))
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
<hr>
|
<hr>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="tabs-inner flex-container-column justify-center">
|
<div class="tabs-inner flex-container-column justify-center">
|
||||||
<button type="button" refs="editor-toolbox@toggle" title="{{ trans('entities.toggle_sidebar') }}" aria-expanded="false" class="toolbox-toggle">@icon('caret-left-circle')</button>
|
<button type="button" refs="editor-toolbox@toggle" title="{{ trans('entities.toggle_sidebar') }}" aria-expanded="false" class="toolbox-toggle">@icon('caret-left-circle')</button>
|
||||||
<button type="button" refs="editor-toolbox@tab-button" data-tab="tags" title="{{ trans('entities.page_tags') }}" class="active">@icon('tag')</button>
|
<button type="button" refs="editor-toolbox@tab-button" data-tab="tags" title="{{ trans('entities.page_tags') }}" class="active">@icon('tag')</button>
|
||||||
@if(userCan('attachment-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::AttachmentCreateAll))
|
||||||
<button type="button" refs="editor-toolbox@tab-button" data-tab="files" title="{{ trans('entities.attachments') }}">@icon('attach')</button>
|
<button type="button" refs="editor-toolbox@tab-button" data-tab="files" title="{{ trans('entities.attachments') }}">@icon('attach')</button>
|
||||||
@endif
|
@endif
|
||||||
<button type="button" refs="editor-toolbox@tab-button" data-tab="templates" title="{{ trans('entities.templates') }}">@icon('template')</button>
|
<button type="button" refs="editor-toolbox@tab-button" data-tab="templates" title="{{ trans('entities.templates') }}">@icon('template')</button>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(userCan('attachment-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::AttachmentCreateAll))
|
||||||
@include('attachments.manager', ['page' => $page])
|
@include('attachments.manager', ['page' => $page])
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@@ -38,17 +38,17 @@
|
|||||||
<input id="name" class="input-base" type="text" name="name" value="{{ $image->name }}">
|
<input id="name" class="input-base" type="text" name="name" value="{{ $image->name }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-container-row justify-space-between gap-m">
|
<div class="flex-container-row justify-space-between gap-m">
|
||||||
@if(userCan('image-delete', $image) || userCan('image-update', $image))
|
@if(userCan(\BookStack\Permissions\Permission::ImageDelete, $image) || userCan(\BookStack\Permissions\Permission::ImageUpdate, $image))
|
||||||
<div component="dropdown"
|
<div component="dropdown"
|
||||||
class="dropdown-container">
|
class="dropdown-container">
|
||||||
<button refs="dropdown@toggle" type="button" class="button icon outline">@icon('more')</button>
|
<button refs="dropdown@toggle" type="button" class="button icon outline">@icon('more')</button>
|
||||||
<div refs="dropdown@menu" class="dropdown-menu anchor-left">
|
<div refs="dropdown@menu" class="dropdown-menu anchor-left">
|
||||||
@if(userCan('image-delete', $image))
|
@if(userCan(\BookStack\Permissions\Permission::ImageDelete, $image))
|
||||||
<button type="button"
|
<button type="button"
|
||||||
id="image-manager-delete"
|
id="image-manager-delete"
|
||||||
class="text-item">{{ trans('common.delete') }}</button>
|
class="text-item">{{ trans('common.delete') }}</button>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('image-update', $image))
|
@if(userCan(\BookStack\Permissions\Permission::ImageUpdate, $image))
|
||||||
<button type="button"
|
<button type="button"
|
||||||
id="image-manager-replace"
|
id="image-manager-replace"
|
||||||
refs="dropzone@select-button"
|
refs="dropzone@select-button"
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
@if($image->createdBy)
|
@if($image->createdBy)
|
||||||
<div>@icon('user') {{ trans('components.image_uploaded_by', ['userName' => $image->createdBy->name]) }}</div>
|
<div>@icon('user') {{ trans('components.image_uploaded_by', ['userName' => $image->createdBy->name]) }}</div>
|
||||||
@endif
|
@endif
|
||||||
@if(($page = $image->getPage()) && userCan('view', $page))
|
@if(($page = $image->getPage()) && userCan(\BookStack\Permissions\Permission::PageView, $page))
|
||||||
<div>
|
<div>
|
||||||
@icon('page')
|
@icon('page')
|
||||||
{!! trans('components.image_uploaded_to', [
|
{!! trans('components.image_uploaded_to', [
|
||||||
|
|||||||
@@ -26,11 +26,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@if(userCan('page-update', $page))
|
@if(userCan(\BookStack\Permissions\Permission::PageUpdate, $page))
|
||||||
<a href="{{ $page->getUrl('/edit') }}" id="pointer-edit" data-edit-href="{{ $page->getUrl('/edit') }}"
|
<a href="{{ $page->getUrl('/edit') }}" id="pointer-edit" data-edit-href="{{ $page->getUrl('/edit') }}"
|
||||||
class="button primary outline icon heading-edit-icon px-xs" title="{{ trans('entities.pages_edit_content_link')}}">@icon('edit')</a>
|
class="button primary outline icon heading-edit-icon px-xs" title="{{ trans('entities.pages_edit_content_link')}}">@icon('edit')</a>
|
||||||
@endif
|
@endif
|
||||||
@if($commentTree->enabled() && userCan('comment-create-all'))
|
@if($commentTree->enabled() && userCan(\BookStack\Permissions\Permission::CommentCreateAll))
|
||||||
<button type="button"
|
<button type="button"
|
||||||
refs="pointer@comment-button"
|
refs="pointer@comment-button"
|
||||||
class="button primary outline icon px-xs m-none" title="{{ trans('entities.comment_add')}}">@icon('comment')</button>
|
class="button primary outline icon px-xs m-none" title="{{ trans('entities.comment_add')}}">@icon('comment')</button>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
@else
|
@else
|
||||||
<a href="{{ $revision->getUrl() }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_preview') }}</a>
|
<a href="{{ $revision->getUrl() }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_preview') }}</a>
|
||||||
|
|
||||||
@if(userCan('page-update', $revision->page))
|
@if(userCan(\BookStack\Permissions\Permission::PageUpdate, $revision->page))
|
||||||
<span class="text-muted opacity-70"> | </span>
|
<span class="text-muted opacity-70"> | </span>
|
||||||
<div component="dropdown" class="dropdown-container">
|
<div component="dropdown" class="dropdown-container">
|
||||||
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('entities.pages_revisions_restore') }}</a>
|
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('entities.pages_revisions_restore') }}</a>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(userCan('page-delete', $revision->page))
|
@if(userCan(\BookStack\Permissions\Permission::PageDelete, $revision->page))
|
||||||
<span class="text-muted opacity-70"> | </span>
|
<span class="text-muted opacity-70"> | </span>
|
||||||
<div component="dropdown" class="dropdown-container">
|
<div component="dropdown" class="dropdown-container">
|
||||||
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('common.delete') }}</a>
|
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('common.delete') }}</a>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div component="template-manager">
|
<div component="template-manager">
|
||||||
@if(userCan('templates-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::TemplatesManage))
|
||||||
<p class="text-muted small mb-none">
|
<p class="text-muted small mb-none">
|
||||||
{{ trans('entities.templates_explain_set_as_template') }}
|
{{ trans('entities.templates_explain_set_as_template') }}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
@if($book->hasPermissions())
|
@if($book->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $book))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $book))
|
||||||
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $book->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.books_permissions_active') }}</div>
|
<div>{{ trans('entities.books_permissions_active') }}</div>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
@if($page->chapter && $page->chapter->hasPermissions())
|
@if($page->chapter && $page->chapter->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $page->chapter))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $page->chapter))
|
||||||
<a href="{{ $page->chapter->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $page->chapter->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.chapters_permissions_active') }}</div>
|
<div>{{ trans('entities.chapters_permissions_active') }}</div>
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
|
|
||||||
@if($page->hasPermissions())
|
@if($page->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $page))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $page))
|
||||||
<a href="{{ $page->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $page->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.pages_permissions_active') }}</div>
|
<div>{{ trans('entities.pages_permissions_active') }}</div>
|
||||||
@@ -140,20 +140,20 @@
|
|||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
|
|
||||||
{{--User Actions--}}
|
{{--User Actions--}}
|
||||||
@if(userCan('page-update', $page))
|
@if(userCan(\BookStack\Permissions\Permission::PageUpdate, $page))
|
||||||
<a href="{{ $page->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
<a href="{{ $page->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
||||||
<span>@icon('edit')</span>
|
<span>@icon('edit')</span>
|
||||||
<span>{{ trans('common.edit') }}</span>
|
<span>{{ trans('common.edit') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCanOnAny('create', \BookStack\Entities\Models\Book::class) || userCanOnAny('create', \BookStack\Entities\Models\Chapter::class) || userCan('page-create-all') || userCan('page-create-own'))
|
@if(userCan(\BookStack\Permissions\Permission::PageCreateAll) || userCan(\BookStack\Permissions\Permission::PageCreateOwn) || userCanOnAny(\BookStack\Permissions\Permission::Create, \BookStack\Entities\Models\Book::class) || userCanOnAny(\BookStack\Permissions\Permission::Create, \BookStack\Entities\Models\Chapter::class))
|
||||||
<a href="{{ $page->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
<a href="{{ $page->getUrl('/copy') }}" data-shortcut="copy" class="icon-list-item">
|
||||||
<span>@icon('copy')</span>
|
<span>@icon('copy')</span>
|
||||||
<span>{{ trans('common.copy') }}</span>
|
<span>{{ trans('common.copy') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('page-update', $page))
|
@if(userCan(\BookStack\Permissions\Permission::PageUpdate, $page))
|
||||||
@if(userCan('page-delete', $page))
|
@if(userCan(\BookStack\Permissions\Permission::PageDelete, $page))
|
||||||
<a href="{{ $page->getUrl('/move') }}" data-shortcut="move" class="icon-list-item">
|
<a href="{{ $page->getUrl('/move') }}" data-shortcut="move" class="icon-list-item">
|
||||||
<span>@icon('folder')</span>
|
<span>@icon('folder')</span>
|
||||||
<span>{{ trans('common.move') }}</span>
|
<span>{{ trans('common.move') }}</span>
|
||||||
@@ -164,13 +164,13 @@
|
|||||||
<span>@icon('history')</span>
|
<span>@icon('history')</span>
|
||||||
<span>{{ trans('entities.revisions') }}</span>
|
<span>{{ trans('entities.revisions') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@if(userCan('restrictions-manage', $page))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $page))
|
||||||
<a href="{{ $page->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
<a href="{{ $page->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
||||||
<span>@icon('lock')</span>
|
<span>@icon('lock')</span>
|
||||||
<span>{{ trans('entities.permissions') }}</span>
|
<span>{{ trans('entities.permissions') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('page-delete', $page))
|
@if(userCan(\BookStack\Permissions\Permission::PageDelete, $page))
|
||||||
<a href="{{ $page->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
<a href="{{ $page->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
||||||
<span>@icon('delete')</span>
|
<span>@icon('delete')</span>
|
||||||
<span>{{ trans('common.delete') }}</span>
|
<span>{{ trans('common.delete') }}</span>
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
@if(!user()->isGuest())
|
@if(!user()->isGuest())
|
||||||
@include('entities.favourite-action', ['entity' => $page])
|
@include('entities.favourite-action', ['entity' => $page])
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('content-export'))
|
@if(userCan(\BookStack\Permissions\Permission::ContentExport))
|
||||||
@include('entities.export-menu', ['entity' => $page])
|
@include('entities.export-menu', ['entity' => $page])
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<label for="setting-app-public" class="setting-list-label">{{ trans('settings.app_public_access') }}</label>
|
<label for="setting-app-public" class="setting-list-label">{{ trans('settings.app_public_access') }}</label>
|
||||||
<p class="small">{!! trans('settings.app_public_access_desc') !!}</p>
|
<p class="small">{!! trans('settings.app_public_access_desc') !!}</p>
|
||||||
@if(userCan('users-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::UsersManage))
|
||||||
<p class="small mb-none">
|
<p class="small mb-none">
|
||||||
<a href="{{ url($guestUser->getEditUrl()) }}">{!! trans('settings.app_public_access_desc_guest') !!}</a>
|
<a href="{{ url($guestUser->getEditUrl()) }}">{!! trans('settings.app_public_access_desc_guest') !!}</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
|
|
||||||
<nav class="active-link-list py-m flex-container-row justify-center wrap">
|
<nav class="active-link-list py-m flex-container-row justify-center wrap">
|
||||||
@if(userCan('settings-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::SettingsManage))
|
||||||
<a href="{{ url('/settings') }}" @if($selected == 'settings') class="active" @endif>@icon('settings'){{ trans('settings.settings') }}</a>
|
<a href="{{ url('/settings') }}" @if($selected == 'settings') class="active" @endif>@icon('settings'){{ trans('settings.settings') }}</a>
|
||||||
<a href="{{ url('/settings/maintenance') }}" @if($selected == 'maintenance') class="active" @endif>@icon('spanner'){{ trans('settings.maint') }}</a>
|
<a href="{{ url('/settings/maintenance') }}" @if($selected == 'maintenance') class="active" @endif>@icon('spanner'){{ trans('settings.maint') }}</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('settings-manage') && userCan('users-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::SettingsManage) && userCan(\BookStack\Permissions\Permission::UsersManage))
|
||||||
<a href="{{ url('/settings/audit') }}" @if($selected == 'audit') class="active" @endif>@icon('open-book'){{ trans('settings.audit') }}</a>
|
<a href="{{ url('/settings/audit') }}" @if($selected == 'audit') class="active" @endif>@icon('open-book'){{ trans('settings.audit') }}</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('users-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::UsersManage))
|
||||||
<a href="{{ url('/settings/users') }}" @if($selected == 'users') class="active" @endif>@icon('users'){{ trans('settings.users') }}</a>
|
<a href="{{ url('/settings/users') }}" @if($selected == 'users') class="active" @endif>@icon('users'){{ trans('settings.users') }}</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('user-roles-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::UserRolesManage))
|
||||||
<a href="{{ url('/settings/roles') }}" @if($selected == 'roles') class="active" @endif>@icon('lock-open'){{ trans('settings.roles') }}</a>
|
<a href="{{ url('/settings/roles') }}" @if($selected == 'roles') class="active" @endif>@icon('lock-open'){{ trans('settings.roles') }}</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('settings-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::SettingsManage))
|
||||||
<a href="{{ url('/settings/webhooks') }}" @if($selected == 'webhooks') class="active" @endif>@icon('webhooks'){{ trans('settings.webhooks') }}</a>
|
<a href="{{ url('/settings/webhooks') }}" @if($selected == 'webhooks') class="active" @endif>@icon('webhooks'){{ trans('settings.webhooks') }}</a>
|
||||||
@endif
|
@endif
|
||||||
</nav>
|
</nav>
|
||||||
@@ -35,11 +35,11 @@
|
|||||||
<img class="avatar small" src="{{ $user->getAvatar(40) }}" alt="{{ $user->name }}">
|
<img class="avatar small" src="{{ $user->getAvatar(40) }}" alt="{{ $user->name }}">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@if(userCan('users-manage') || user()->id == $user->id)
|
@if(userCan(\BookStack\Permissions\Permission::UsersManage) || user()->id == $user->id)
|
||||||
<a href="{{ url("/settings/users/{$user->id}") }}">
|
<a href="{{ url("/settings/users/{$user->id}") }}">
|
||||||
@endif
|
@endif
|
||||||
{{ $user->name }}
|
{{ $user->name }}
|
||||||
@if(userCan('users-manage') || user()->id == $user->id)
|
@if(userCan(\BookStack\Permissions\Permission::UsersManage) || user()->id == $user->id)
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="actions mb-xl">
|
<div class="actions mb-xl">
|
||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
@if(userCan('bookshelf-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfCreateAll))
|
||||||
<a href="{{ url("/create-shelf") }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ url("/create-shelf") }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span>@icon('add')</span>
|
<span>@icon('add')</span>
|
||||||
<span>{{ trans('entities.shelves_new_action') }}</span>
|
<span>{{ trans('entities.shelves_new_action') }}</span>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p class="text-muted">{{ trans('entities.shelves_empty') }}</p>
|
<p class="text-muted">{{ trans('entities.shelves_empty') }}</p>
|
||||||
@if(userCan('bookshelf-create-all'))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfCreateAll))
|
||||||
<div class="icon-list block inline">
|
<div class="icon-list block inline">
|
||||||
<a href="{{ url("/create-shelf") }}"
|
<a href="{{ url("/create-shelf") }}"
|
||||||
class="icon-list-item text-bookshelf">
|
class="icon-list-item text-bookshelf">
|
||||||
|
|||||||
@@ -48,13 +48,13 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<p class="text-muted italic mt-xl mb-m">{{ trans('entities.shelves_empty_contents') }}</p>
|
<p class="text-muted italic mt-xl mb-m">{{ trans('entities.shelves_empty_contents') }}</p>
|
||||||
<div class="icon-list inline block">
|
<div class="icon-list inline block">
|
||||||
@if(userCan('book-create-all') && userCan('bookshelf-update', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll) && userCan(\BookStack\Permissions\Permission::BookshelfUpdate, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/create-book') }}" class="icon-list-item text-book">
|
<a href="{{ $shelf->getUrl('/create-book') }}" class="icon-list-item text-book">
|
||||||
<span class="icon">@icon('add')</span>
|
<span class="icon">@icon('add')</span>
|
||||||
<span>{{ trans('entities.books_create') }}</span>
|
<span>{{ trans('entities.books_create') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
@if(userCan('bookshelf-update', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfUpdate, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/edit') }}" class="icon-list-item text-bookshelf">
|
<a href="{{ $shelf->getUrl('/edit') }}" class="icon-list-item text-bookshelf">
|
||||||
<span class="icon">@icon('edit')</span>
|
<span class="icon">@icon('edit')</span>
|
||||||
<span>{{ trans('entities.shelves_edit_and_assign') }}</span>
|
<span>{{ trans('entities.shelves_edit_and_assign') }}</span>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
@include('entities.meta', ['entity' => $shelf, 'watchOptions' => null])
|
@include('entities.meta', ['entity' => $shelf, 'watchOptions' => null])
|
||||||
@if($shelf->hasPermissions())
|
@if($shelf->hasPermissions())
|
||||||
<div class="active-restriction">
|
<div class="active-restriction">
|
||||||
@if(userCan('restrictions-manage', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/permissions') }}" class="entity-meta-item">
|
<a href="{{ $shelf->getUrl('/permissions') }}" class="entity-meta-item">
|
||||||
@icon('lock')
|
@icon('lock')
|
||||||
<div>{{ trans('entities.shelves_permissions_active') }}</div>
|
<div>{{ trans('entities.shelves_permissions_active') }}</div>
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
<h5>{{ trans('common.actions') }}</h5>
|
<h5>{{ trans('common.actions') }}</h5>
|
||||||
<div class="icon-list text-link">
|
<div class="icon-list text-link">
|
||||||
|
|
||||||
@if(userCan('book-create-all') && userCan('bookshelf-update', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::BookCreateAll) && userCan(\BookStack\Permissions\Permission::BookshelfUpdate, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/create-book') }}" data-shortcut="new" class="icon-list-item">
|
<a href="{{ $shelf->getUrl('/create-book') }}" data-shortcut="new" class="icon-list-item">
|
||||||
<span class="icon">@icon('add')</span>
|
<span class="icon">@icon('add')</span>
|
||||||
<span>{{ trans('entities.books_new_action') }}</span>
|
<span>{{ trans('entities.books_new_action') }}</span>
|
||||||
@@ -122,21 +122,21 @@
|
|||||||
|
|
||||||
<hr class="primary-background">
|
<hr class="primary-background">
|
||||||
|
|
||||||
@if(userCan('bookshelf-update', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfUpdate, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
<a href="{{ $shelf->getUrl('/edit') }}" data-shortcut="edit" class="icon-list-item">
|
||||||
<span>@icon('edit')</span>
|
<span>@icon('edit')</span>
|
||||||
<span>{{ trans('common.edit') }}</span>
|
<span>{{ trans('common.edit') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(userCan('restrictions-manage', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::RestrictionsManage, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
<a href="{{ $shelf->getUrl('/permissions') }}" data-shortcut="permissions" class="icon-list-item">
|
||||||
<span>@icon('lock')</span>
|
<span>@icon('lock')</span>
|
||||||
<span>{{ trans('entities.permissions') }}</span>
|
<span>{{ trans('entities.permissions') }}</span>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(userCan('bookshelf-delete', $shelf))
|
@if(userCan(\BookStack\Permissions\Permission::BookshelfDelete, $shelf))
|
||||||
<a href="{{ $shelf->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
<a href="{{ $shelf->getUrl('/delete') }}" data-shortcut="delete" class="icon-list-item">
|
||||||
<span>@icon('delete')</span>
|
<span>@icon('delete')</span>
|
||||||
<span>{{ trans('common.delete') }}</span>
|
<span>{{ trans('common.delete') }}</span>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
</section>
|
</section>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(userCan('access-api'))
|
@if(userCan(\BookStack\Permissions\Permission::AccessApi))
|
||||||
@include('users.api-tokens.parts.list', ['user' => user(), 'context' => 'my-account'])
|
@include('users.api-tokens.parts.list', ['user' => user(), 'context' => 'my-account'])
|
||||||
@endif
|
@endif
|
||||||
@stop
|
@stop
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<p>{{ trans('preferences.delete_my_account_desc') }}</p>
|
<p>{{ trans('preferences.delete_my_account_desc') }}</p>
|
||||||
|
|
||||||
@if(userCan('users-manage'))
|
@if(userCan(\BookStack\Permissions\Permission::UsersManage))
|
||||||
<hr class="my-l">
|
<hr class="my-l">
|
||||||
|
|
||||||
<div class="grid half gap-xl v-center">
|
<div class="grid half gap-xl v-center">
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<a href="{{ url('/my-account/profile') }}" class="{{ $category === 'profile' ? 'active' : '' }}">@icon('user') {{ trans('preferences.profile') }}</a>
|
<a href="{{ url('/my-account/profile') }}" class="{{ $category === 'profile' ? 'active' : '' }}">@icon('user') {{ trans('preferences.profile') }}</a>
|
||||||
<a href="{{ url('/my-account/auth') }}" class="{{ $category === 'auth' ? 'active' : '' }}">@icon('security') {{ trans('preferences.auth') }}</a>
|
<a href="{{ url('/my-account/auth') }}" class="{{ $category === 'auth' ? 'active' : '' }}">@icon('security') {{ trans('preferences.auth') }}</a>
|
||||||
<a href="{{ url('/my-account/shortcuts') }}" class="{{ $category === 'shortcuts' ? 'active' : '' }}">@icon('shortcuts') {{ trans('preferences.shortcuts_interface') }}</a>
|
<a href="{{ url('/my-account/shortcuts') }}" class="{{ $category === 'shortcuts' ? 'active' : '' }}">@icon('shortcuts') {{ trans('preferences.shortcuts_interface') }}</a>
|
||||||
@if(userCan('receive-notifications'))
|
@if(userCan(\BookStack\Permissions\Permission::ReceiveNotifications))
|
||||||
<a href="{{ url('/my-account/notifications') }}" class="{{ $category === 'notifications' ? 'active' : '' }}">@icon('notifications') {{ trans('preferences.notifications') }}</a>
|
<a href="{{ url('/my-account/notifications') }}" class="{{ $category === 'notifications' ? 'active' : '' }}">@icon('notifications') {{ trans('preferences.notifications') }}</a>
|
||||||
@endif
|
@endif
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user