Major permission naming refactor and database migration cleanup
This commit is contained in:
		
							parent
							
								
									05666efda9
								
							
						
					
					
						commit
						75a4fc905b
					
				| 
						 | 
				
			
			@ -26,7 +26,7 @@ class Activity extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function user()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User');
 | 
			
		||||
        return $this->belongsTo(User::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								app/Book.php
								
								
								
								
							
							
						
						
									
										32
									
								
								app/Book.php
								
								
								
								
							| 
						 | 
				
			
			@ -1,35 +1,55 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack;
 | 
			
		||||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
class Book extends Entity
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    protected $fillable = ['name', 'description'];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the url for this book.
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getUrl()
 | 
			
		||||
    {
 | 
			
		||||
        return '/books/' . $this->slug;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Get the edit url for this book.
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getEditUrl()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->getUrl() . '/edit';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all pages within this book.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
 | 
			
		||||
     */
 | 
			
		||||
    public function pages()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany('BookStack\Page');
 | 
			
		||||
        return $this->hasMany(Page::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all chapters within this book.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
 | 
			
		||||
     */
 | 
			
		||||
    public function chapters()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany('BookStack\Chapter');
 | 
			
		||||
        return $this->hasMany(Chapter::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an excerpt of this book's description to the specified length or less.
 | 
			
		||||
     * @param int $length
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getExcerpt($length = 100)
 | 
			
		||||
    {
 | 
			
		||||
        return strlen($this->description) > $length ? substr($this->description, 0, $length-3) . '...' : $this->description;
 | 
			
		||||
        $description = $this->description;
 | 
			
		||||
        return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,25 +5,43 @@ class Chapter extends Entity
 | 
			
		|||
{
 | 
			
		||||
    protected $fillable = ['name', 'description', 'priority', 'book_id'];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the book this chapter is within.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     */
 | 
			
		||||
    public function book()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\Book');
 | 
			
		||||
        return $this->belongsTo(Book::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the pages that this chapter contains.
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function pages()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany('BookStack\Page')->orderBy('priority', 'ASC');
 | 
			
		||||
        return $this->hasMany(Page::class)->orderBy('priority', 'ASC');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the url of this chapter.
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getUrl()
 | 
			
		||||
    {
 | 
			
		||||
        $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
 | 
			
		||||
        return '/books/' . $bookSlug. '/chapter/' . $this->slug;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an excerpt of this chapter's description to the specified length or less.
 | 
			
		||||
     * @param int $length
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getExcerpt($length = 100)
 | 
			
		||||
    {
 | 
			
		||||
        return strlen($this->description) > $length ? substr($this->description, 0, $length-3) . '...' : $this->description;
 | 
			
		||||
        $description = $this->description;
 | 
			
		||||
        return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use BookStack\Services\RestrictionService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
 | 
			
		||||
class RegeneratePermissions extends Command
 | 
			
		||||
| 
						 | 
				
			
			@ -24,18 +24,18 @@ class RegeneratePermissions extends Command
 | 
			
		|||
    /**
 | 
			
		||||
     * The service to handle the permission system.
 | 
			
		||||
     *
 | 
			
		||||
     * @var RestrictionService
 | 
			
		||||
     * @var PermissionService
 | 
			
		||||
     */
 | 
			
		||||
    protected $restrictionService;
 | 
			
		||||
    protected $permissionService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param RestrictionService $restrictionService
 | 
			
		||||
     * @param PermissionService $permissionService
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(RestrictionService $restrictionService)
 | 
			
		||||
    public function __construct(PermissionService $permissionService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->restrictionService = $restrictionService;
 | 
			
		||||
        $this->permissionService = $permissionService;
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +46,6 @@ class RegeneratePermissions extends Command
 | 
			
		|||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $this->restrictionService->buildEntityPermissions();
 | 
			
		||||
        $this->permissionService->buildJointPermissions();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,16 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace BookStack;
 | 
			
		||||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
class EmailConfirmation extends Model
 | 
			
		||||
{
 | 
			
		||||
    protected $fillable = ['user_id', 'token'];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the user that this confirmation is attached to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     */
 | 
			
		||||
    public function user()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User');
 | 
			
		||||
        return $this->belongsTo(User::class);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ abstract class Entity extends Ownable
 | 
			
		|||
     */
 | 
			
		||||
    public function activity()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphMany('BookStack\Activity', 'entity')->orderBy('created_at', 'desc');
 | 
			
		||||
        return $this->morphMany(Activity::class, 'entity')->orderBy('created_at', 'desc');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -51,15 +51,15 @@ abstract class Entity extends Ownable
 | 
			
		|||
     */
 | 
			
		||||
    public function views()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphMany('BookStack\View', 'viewable');
 | 
			
		||||
        return $this->morphMany(View::class, 'viewable');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get this entities restrictions.
 | 
			
		||||
     */
 | 
			
		||||
    public function restrictions()
 | 
			
		||||
    public function permissions()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphMany('BookStack\Restriction', 'restrictable');
 | 
			
		||||
        return $this->morphMany(EntityPermission::class, 'restrictable');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ abstract class Entity extends Ownable
 | 
			
		|||
     */
 | 
			
		||||
    public function hasRestriction($role_id, $action)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->restrictions()->where('role_id', '=', $role_id)
 | 
			
		||||
        return $this->permissions()->where('role_id', '=', $role_id)
 | 
			
		||||
            ->where('action', '=', $action)->count() > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,12 +86,12 @@ abstract class Entity extends Ownable
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the entity permissions this is connected to.
 | 
			
		||||
     * Get the entity jointPermissions this is connected to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 | 
			
		||||
     */
 | 
			
		||||
    public function permissions()
 | 
			
		||||
    public function jointPermissions()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphMany(EntityPermission::class, 'entity');
 | 
			
		||||
        return $this->morphMany(JointPermission::class, 'entity');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,24 +1,18 @@
 | 
			
		|||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EntityPermission extends Model
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    protected $fillable = ['role_id', 'action'];
 | 
			
		||||
    public $timestamps = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the role that this points to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     * Get all this restriction's attached entity.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
 | 
			
		||||
     */
 | 
			
		||||
    public function role()
 | 
			
		||||
    public function restrictable()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo(Role::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the entity this points to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
 | 
			
		||||
     */
 | 
			
		||||
    public function entity()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphOne(Entity::class, 'entity');
 | 
			
		||||
        return $this->morphTo('restrictable');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -252,7 +252,7 @@ class BookController extends Controller
 | 
			
		|||
    {
 | 
			
		||||
        $book = $this->bookRepo->getBySlug($bookSlug);
 | 
			
		||||
        $this->checkOwnablePermission('restrictions-manage', $book);
 | 
			
		||||
        $this->bookRepo->updateRestrictionsFromRequest($request, $book);
 | 
			
		||||
        $this->bookRepo->updateEntityPermissionsFromRequest($request, $book);
 | 
			
		||||
        session()->flash('success', 'Book Restrictions Updated');
 | 
			
		||||
        return redirect($book->getUrl());
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,7 +184,7 @@ class ChapterController extends Controller
 | 
			
		|||
        $book = $this->bookRepo->getBySlug($bookSlug);
 | 
			
		||||
        $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
 | 
			
		||||
        $this->checkOwnablePermission('restrictions-manage', $chapter);
 | 
			
		||||
        $this->chapterRepo->updateRestrictionsFromRequest($request, $chapter);
 | 
			
		||||
        $this->chapterRepo->updateEntityPermissionsFromRequest($request, $chapter);
 | 
			
		||||
        session()->flash('success', 'Chapter Restrictions Updated');
 | 
			
		||||
        return redirect($chapter->getUrl());
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -451,7 +451,7 @@ class PageController extends Controller
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the restrictions for this page.
 | 
			
		||||
     * Set the permissions for this page.
 | 
			
		||||
     * @param $bookSlug
 | 
			
		||||
     * @param $pageSlug
 | 
			
		||||
     * @param Request $request
 | 
			
		||||
| 
						 | 
				
			
			@ -462,8 +462,8 @@ class PageController extends Controller
 | 
			
		|||
        $book = $this->bookRepo->getBySlug($bookSlug);
 | 
			
		||||
        $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
 | 
			
		||||
        $this->checkOwnablePermission('restrictions-manage', $page);
 | 
			
		||||
        $this->pageRepo->updateRestrictionsFromRequest($request, $page);
 | 
			
		||||
        session()->flash('success', 'Page Restrictions Updated');
 | 
			
		||||
        $this->pageRepo->updateEntityPermissionsFromRequest($request, $page);
 | 
			
		||||
        session()->flash('success', 'Page Permissions Updated');
 | 
			
		||||
        return redirect($page->getUrl());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
use BookStack\Exceptions\PermissionsException;
 | 
			
		||||
use BookStack\Repos\PermissionsRepo;
 | 
			
		||||
use BookStack\Services\RestrictionService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use BookStack\Http\Requests;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
class JointPermission extends Model
 | 
			
		||||
{
 | 
			
		||||
    public $timestamps = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the role that this points to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     */
 | 
			
		||||
    public function role()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo(Role::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the entity this points to.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
 | 
			
		||||
     */
 | 
			
		||||
    public function entity()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphOne(Entity::class, 'entity');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ abstract class Ownable extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function createdBy()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User', 'created_by');
 | 
			
		||||
        return $this->belongsTo(User::class, 'created_by');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ abstract class Ownable extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function updatedBy()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User', 'updated_by');
 | 
			
		||||
        return $this->belongsTo(User::class, 'updated_by');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								app/Page.php
								
								
								
								
							
							
						
						
									
										35
									
								
								app/Page.php
								
								
								
								
							| 
						 | 
				
			
			@ -7,6 +7,10 @@ class Page extends Entity
 | 
			
		|||
 | 
			
		||||
    protected $simpleAttributes = ['name', 'id', 'slug'];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts this page into a simplified array.
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function toSimpleArray()
 | 
			
		||||
    {
 | 
			
		||||
        $array = array_intersect_key($this->toArray(), array_flip($this->simpleAttributes));
 | 
			
		||||
| 
						 | 
				
			
			@ -14,26 +18,46 @@ class Page extends Entity
 | 
			
		|||
        return $array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the book this page sits in.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     */
 | 
			
		||||
    public function book()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\Book');
 | 
			
		||||
        return $this->belongsTo(Book::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the chapter that this page is in, If applicable.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
			
		||||
     */
 | 
			
		||||
    public function chapter()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\Chapter');
 | 
			
		||||
        return $this->belongsTo(Chapter::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if this page has a chapter.
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function hasChapter()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->chapter()->count() > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the associated page revisions, ordered by created date.
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function revisions()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany('BookStack\PageRevision')->where('type', '=', 'version')->orderBy('created_at', 'desc');
 | 
			
		||||
        return $this->hasMany(PageRevision::class)->where('type', '=', 'version')->orderBy('created_at', 'desc');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the url for this page.
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getUrl()
 | 
			
		||||
    {
 | 
			
		||||
        $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +66,11 @@ class Page extends Entity
 | 
			
		|||
        return '/books/' . $bookSlug . $midText . $idComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an excerpt of this page's content to the specified length.
 | 
			
		||||
     * @param int $length
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function getExcerpt($length = 100)
 | 
			
		||||
    {
 | 
			
		||||
        $text = strlen($this->text) > $length ? substr($this->text, 0, $length-3) . '...' : $this->text;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ class PageRevision extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function createdBy()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User', 'created_by');
 | 
			
		||||
        return $this->belongsTo(User::class, 'created_by');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ class PageRevision extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function page()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\Page');
 | 
			
		||||
        return $this->belongsTo(Page::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
namespace BookStack\Providers;
 | 
			
		||||
 | 
			
		||||
use Auth;
 | 
			
		||||
use BookStack\Services\LdapService;
 | 
			
		||||
use Illuminate\Support\ServiceProvider;
 | 
			
		||||
 | 
			
		||||
class AuthServiceProvider extends ServiceProvider
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +26,7 @@ class AuthServiceProvider extends ServiceProvider
 | 
			
		|||
    public function register()
 | 
			
		||||
    {
 | 
			
		||||
        Auth::provider('ldap', function($app, array $config) {
 | 
			
		||||
            return new LdapUserProvider($config['model'], $app['BookStack\Services\LdapService']);
 | 
			
		||||
            return new LdapUserProvider($config['model'], $app[LdapService::class]);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,11 +2,18 @@
 | 
			
		|||
 | 
			
		||||
namespace BookStack\Providers;
 | 
			
		||||
 | 
			
		||||
use BookStack\Activity;
 | 
			
		||||
use BookStack\Services\ImageService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use BookStack\Services\ViewService;
 | 
			
		||||
use BookStack\Setting;
 | 
			
		||||
use BookStack\View;
 | 
			
		||||
use Illuminate\Contracts\Cache\Repository;
 | 
			
		||||
use Illuminate\Contracts\Filesystem\Factory;
 | 
			
		||||
use Illuminate\Support\ServiceProvider;
 | 
			
		||||
use BookStack\Services\ActivityService;
 | 
			
		||||
use BookStack\Services\SettingService;
 | 
			
		||||
use Intervention\Image\ImageManager;
 | 
			
		||||
 | 
			
		||||
class CustomFacadeProvider extends ServiceProvider
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -29,30 +36,30 @@ class CustomFacadeProvider extends ServiceProvider
 | 
			
		|||
    {
 | 
			
		||||
        $this->app->bind('activity', function() {
 | 
			
		||||
            return new ActivityService(
 | 
			
		||||
                $this->app->make('BookStack\Activity'),
 | 
			
		||||
                $this->app->make('BookStack\Services\RestrictionService')
 | 
			
		||||
                $this->app->make(Activity::class),
 | 
			
		||||
                $this->app->make(PermissionService::class)
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this->app->bind('views', function() {
 | 
			
		||||
            return new ViewService(
 | 
			
		||||
                $this->app->make('BookStack\View'),
 | 
			
		||||
                $this->app->make('BookStack\Services\RestrictionService')
 | 
			
		||||
                $this->app->make(View::class),
 | 
			
		||||
                $this->app->make(PermissionService::class)
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this->app->bind('setting', function() {
 | 
			
		||||
            return new SettingService(
 | 
			
		||||
                $this->app->make('BookStack\Setting'),
 | 
			
		||||
                $this->app->make('Illuminate\Contracts\Cache\Repository')
 | 
			
		||||
                $this->app->make(Setting::class),
 | 
			
		||||
                $this->app->make(Repository::class)
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this->app->bind('images', function() {
 | 
			
		||||
            return new ImageService(
 | 
			
		||||
                $this->app->make('Intervention\Image\ImageManager'),
 | 
			
		||||
                $this->app->make('Illuminate\Contracts\Filesystem\Factory'),
 | 
			
		||||
                $this->app->make('Illuminate\Contracts\Cache\Repository')
 | 
			
		||||
                $this->app->make(ImageManager::class),
 | 
			
		||||
                $this->app->make(Factory::class),
 | 
			
		||||
                $this->app->make(Repository::class)
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ class BookRepo extends EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    private function bookQuery()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->restrictionService->enforceBookRestrictions($this->book, 'view');
 | 
			
		||||
        return $this->permissionService->enforceBookRestrictions($this->book, 'view');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ class BookRepo extends EntityRepo
 | 
			
		|||
        $book->created_by = auth()->user()->id;
 | 
			
		||||
        $book->updated_by = auth()->user()->id;
 | 
			
		||||
        $book->save();
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($book);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($book);
 | 
			
		||||
        return $book;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,7 +150,7 @@ class BookRepo extends EntityRepo
 | 
			
		|||
        $book->slug = $this->findSuitableSlug($book->name, $book->id);
 | 
			
		||||
        $book->updated_by = auth()->user()->id;
 | 
			
		||||
        $book->save();
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($book);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($book);
 | 
			
		||||
        return $book;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,18 +168,18 @@ class BookRepo extends EntityRepo
 | 
			
		|||
            $this->chapterRepo->destroy($chapter);
 | 
			
		||||
        }
 | 
			
		||||
        $book->views()->delete();
 | 
			
		||||
        $book->restrictions()->delete();
 | 
			
		||||
        $this->restrictionService->deleteEntityPermissionsForEntity($book);
 | 
			
		||||
        $book->permissions()->delete();
 | 
			
		||||
        $this->permissionService->deleteJointPermissionsForEntity($book);
 | 
			
		||||
        $book->delete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Alias method to update the book permissions in the RestrictionService.
 | 
			
		||||
     * Alias method to update the book jointPermissions in the PermissionService.
 | 
			
		||||
     * @param Book $book
 | 
			
		||||
     */
 | 
			
		||||
    public function updateBookPermissions(Book $book)
 | 
			
		||||
    {
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($book);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($book);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ class BookRepo extends EntityRepo
 | 
			
		|||
    public function getChildren(Book $book, $filterDrafts = false)
 | 
			
		||||
    {
 | 
			
		||||
        $pageQuery = $book->pages()->where('chapter_id', '=', 0);
 | 
			
		||||
        $pageQuery = $this->restrictionService->enforcePageRestrictions($pageQuery, 'view');
 | 
			
		||||
        $pageQuery = $this->permissionService->enforcePageRestrictions($pageQuery, 'view');
 | 
			
		||||
 | 
			
		||||
        if ($filterDrafts) {
 | 
			
		||||
            $pageQuery = $pageQuery->where('draft', '=', false);
 | 
			
		||||
| 
						 | 
				
			
			@ -246,10 +246,10 @@ class BookRepo extends EntityRepo
 | 
			
		|||
        $pages = $pageQuery->get();
 | 
			
		||||
 | 
			
		||||
        $chapterQuery = $book->chapters()->with(['pages' => function($query) use ($filterDrafts) {
 | 
			
		||||
            $this->restrictionService->enforcePageRestrictions($query, 'view');
 | 
			
		||||
            $this->permissionService->enforcePageRestrictions($query, 'view');
 | 
			
		||||
            if ($filterDrafts) $query->where('draft', '=', false);
 | 
			
		||||
        }]);
 | 
			
		||||
        $chapterQuery = $this->restrictionService->enforceChapterRestrictions($chapterQuery, 'view');
 | 
			
		||||
        $chapterQuery = $this->permissionService->enforceChapterRestrictions($chapterQuery, 'view');
 | 
			
		||||
        $chapters = $chapterQuery->get();
 | 
			
		||||
        $children = $pages->merge($chapters);
 | 
			
		||||
        $bookSlug = $book->slug;
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +286,7 @@ class BookRepo extends EntityRepo
 | 
			
		|||
    public function getBySearch($term, $count = 20, $paginationAppends = [])
 | 
			
		||||
    {
 | 
			
		||||
        $terms = $this->prepareSearchTerms($term);
 | 
			
		||||
        $books = $this->restrictionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
 | 
			
		||||
        $books = $this->permissionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
 | 
			
		||||
            ->paginate($count)->appends($paginationAppends);
 | 
			
		||||
        $words = join('|', explode(' ', preg_quote(trim($term), '/')));
 | 
			
		||||
        foreach ($books as $book) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,12 +10,12 @@ use BookStack\Chapter;
 | 
			
		|||
class ChapterRepo extends EntityRepo
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Base query for getting chapters, Takes restrictions into account.
 | 
			
		||||
     * Base query for getting chapters, Takes permissions into account.
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    private function chapterQuery()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->restrictionService->enforceChapterRestrictions($this->chapter, 'view');
 | 
			
		||||
        return $this->permissionService->enforceChapterRestrictions($this->chapter, 'view');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ class ChapterRepo extends EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getChildren(Chapter $chapter)
 | 
			
		||||
    {
 | 
			
		||||
        $pages = $this->restrictionService->enforcePageRestrictions($chapter->pages())->get();
 | 
			
		||||
        $pages = $this->permissionService->enforcePageRestrictions($chapter->pages())->get();
 | 
			
		||||
        // Sort items with drafts first then by priority.
 | 
			
		||||
        return $pages->sortBy(function($child, $key) {
 | 
			
		||||
            $score = $child->priority;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ class ChapterRepo extends EntityRepo
 | 
			
		|||
        $chapter->created_by = auth()->user()->id;
 | 
			
		||||
        $chapter->updated_by = auth()->user()->id;
 | 
			
		||||
        $chapter = $book->chapters()->save($chapter);
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($chapter);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($chapter);
 | 
			
		||||
        return $chapter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,8 +107,8 @@ class ChapterRepo extends EntityRepo
 | 
			
		|||
        }
 | 
			
		||||
        Activity::removeEntity($chapter);
 | 
			
		||||
        $chapter->views()->delete();
 | 
			
		||||
        $chapter->restrictions()->delete();
 | 
			
		||||
        $this->restrictionService->deleteEntityPermissionsForEntity($chapter);
 | 
			
		||||
        $chapter->permissions()->delete();
 | 
			
		||||
        $this->permissionService->deleteJointPermissionsForEntity($chapter);
 | 
			
		||||
        $chapter->delete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ class ChapterRepo extends EntityRepo
 | 
			
		|||
    public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
 | 
			
		||||
    {
 | 
			
		||||
        $terms = $this->prepareSearchTerms($term);
 | 
			
		||||
        $chapters = $this->restrictionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
 | 
			
		||||
        $chapters = $this->permissionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
 | 
			
		||||
            ->paginate($count)->appends($paginationAppends);
 | 
			
		||||
        $words = join('|', explode(' ', preg_quote(trim($term), '/')));
 | 
			
		||||
        foreach ($chapters as $chapter) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ use BookStack\Book;
 | 
			
		|||
use BookStack\Chapter;
 | 
			
		||||
use BookStack\Entity;
 | 
			
		||||
use BookStack\Page;
 | 
			
		||||
use BookStack\Services\RestrictionService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use BookStack\User;
 | 
			
		||||
 | 
			
		||||
class EntityRepo
 | 
			
		||||
| 
						 | 
				
			
			@ -26,9 +26,9 @@ class EntityRepo
 | 
			
		|||
    public $page;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var RestrictionService
 | 
			
		||||
     * @var PermissionService
 | 
			
		||||
     */
 | 
			
		||||
    protected $restrictionService;
 | 
			
		||||
    protected $permissionService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EntityService constructor.
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ class EntityRepo
 | 
			
		|||
        $this->book = app(Book::class);
 | 
			
		||||
        $this->chapter = app(Chapter::class);
 | 
			
		||||
        $this->page = app(Page::class);
 | 
			
		||||
        $this->restrictionService = app(RestrictionService::class);
 | 
			
		||||
        $this->permissionService = app(PermissionService::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ class EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getRecentlyCreatedBooks($count = 20, $page = 0, $additionalQuery = false)
 | 
			
		||||
    {
 | 
			
		||||
        $query = $this->restrictionService->enforceBookRestrictions($this->book)
 | 
			
		||||
        $query = $this->permissionService->enforceBookRestrictions($this->book)
 | 
			
		||||
            ->orderBy('created_at', 'desc');
 | 
			
		||||
        if ($additionalQuery !== false && is_callable($additionalQuery)) {
 | 
			
		||||
            $additionalQuery($query);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ class EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getRecentlyUpdatedBooks($count = 20, $page = 0)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->restrictionService->enforceBookRestrictions($this->book)
 | 
			
		||||
        return $this->permissionService->enforceBookRestrictions($this->book)
 | 
			
		||||
            ->orderBy('updated_at', 'desc')->skip($page * $count)->take($count)->get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +79,7 @@ class EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getRecentlyCreatedPages($count = 20, $page = 0, $additionalQuery = false)
 | 
			
		||||
    {
 | 
			
		||||
        $query = $this->restrictionService->enforcePageRestrictions($this->page)
 | 
			
		||||
        $query = $this->permissionService->enforcePageRestrictions($this->page)
 | 
			
		||||
            ->orderBy('created_at', 'desc')->where('draft', '=', false);
 | 
			
		||||
        if ($additionalQuery !== false && is_callable($additionalQuery)) {
 | 
			
		||||
            $additionalQuery($query);
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ class EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getRecentlyCreatedChapters($count = 20, $page = 0, $additionalQuery = false)
 | 
			
		||||
    {
 | 
			
		||||
        $query = $this->restrictionService->enforceChapterRestrictions($this->chapter)
 | 
			
		||||
        $query = $this->permissionService->enforceChapterRestrictions($this->chapter)
 | 
			
		||||
            ->orderBy('created_at', 'desc');
 | 
			
		||||
        if ($additionalQuery !== false && is_callable($additionalQuery)) {
 | 
			
		||||
            $additionalQuery($query);
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ class EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    public function getRecentlyUpdatedPages($count = 20, $page = 0)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->restrictionService->enforcePageRestrictions($this->page)
 | 
			
		||||
        return $this->permissionService->enforcePageRestrictions($this->page)
 | 
			
		||||
            ->where('draft', '=', false)
 | 
			
		||||
            ->orderBy('updated_at', 'desc')->with('book')->skip($page * $count)->take($count)->get();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -136,14 +136,14 @@ class EntityRepo
 | 
			
		|||
     * @param $request
 | 
			
		||||
     * @param Entity $entity
 | 
			
		||||
     */
 | 
			
		||||
    public function updateRestrictionsFromRequest($request, Entity $entity)
 | 
			
		||||
    public function updateEntityPermissionsFromRequest($request, Entity $entity)
 | 
			
		||||
    {
 | 
			
		||||
        $entity->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
 | 
			
		||||
        $entity->restrictions()->delete();
 | 
			
		||||
        $entity->permissions()->delete();
 | 
			
		||||
        if ($request->has('restrictions')) {
 | 
			
		||||
            foreach ($request->get('restrictions') as $roleId => $restrictions) {
 | 
			
		||||
                foreach ($restrictions as $action => $value) {
 | 
			
		||||
                    $entity->restrictions()->create([
 | 
			
		||||
                    $entity->permissions()->create([
 | 
			
		||||
                        'role_id' => $roleId,
 | 
			
		||||
                        'action'  => strtolower($action)
 | 
			
		||||
                    ]);
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ class EntityRepo
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $entity->save();
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($entity);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($entity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
use BookStack\Image;
 | 
			
		||||
use BookStack\Page;
 | 
			
		||||
use BookStack\Services\ImageService;
 | 
			
		||||
use BookStack\Services\RestrictionService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use Setting;
 | 
			
		||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,14 +20,14 @@ class ImageRepo
 | 
			
		|||
     * ImageRepo constructor.
 | 
			
		||||
     * @param Image $image
 | 
			
		||||
     * @param ImageService $imageService
 | 
			
		||||
     * @param RestrictionService $restrictionService
 | 
			
		||||
     * @param PermissionService $permissionService
 | 
			
		||||
     * @param Page $page
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Image $image, ImageService $imageService, RestrictionService $restrictionService, Page $page)
 | 
			
		||||
    public function __construct(Image $image, ImageService $imageService, PermissionService $permissionService, Page $page)
 | 
			
		||||
    {
 | 
			
		||||
        $this->image = $image;
 | 
			
		||||
        $this->imageService = $imageService;
 | 
			
		||||
        $this->restictionService = $restrictionService;
 | 
			
		||||
        $this->restictionService = $permissionService;
 | 
			
		||||
        $this->page = $page;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ class PageRepo extends EntityRepo
 | 
			
		|||
     */
 | 
			
		||||
    private function pageQuery($allowDrafts = false)
 | 
			
		||||
    {
 | 
			
		||||
        $query = $this->restrictionService->enforcePageRestrictions($this->page, 'view');
 | 
			
		||||
        $query = $this->permissionService->enforcePageRestrictions($this->page, 'view');
 | 
			
		||||
        if (!$allowDrafts) {
 | 
			
		||||
            $query = $query->where('draft', '=', false);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ class PageRepo extends EntityRepo
 | 
			
		|||
    {
 | 
			
		||||
        $revision = $this->pageRevision->where('slug', '=', $pageSlug)
 | 
			
		||||
            ->whereHas('page', function ($query) {
 | 
			
		||||
                $this->restrictionService->enforcePageRestrictions($query);
 | 
			
		||||
                $this->permissionService->enforcePageRestrictions($query);
 | 
			
		||||
            })
 | 
			
		||||
            ->where('type', '=', 'version')
 | 
			
		||||
            ->where('book_slug', '=', $bookSlug)->orderBy('created_at', 'desc')
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ class PageRepo extends EntityRepo
 | 
			
		|||
        if ($chapter) $page->chapter_id = $chapter->id;
 | 
			
		||||
 | 
			
		||||
        $book->pages()->save($page);
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($page);
 | 
			
		||||
        $this->permissionService->buildJointPermissionsForEntity($page);
 | 
			
		||||
        return $page;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ class PageRepo extends EntityRepo
 | 
			
		|||
    public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
 | 
			
		||||
    {
 | 
			
		||||
        $terms = $this->prepareSearchTerms($term);
 | 
			
		||||
        $pages = $this->restrictionService->enforcePageRestrictions($this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms))
 | 
			
		||||
        $pages = $this->permissionService->enforcePageRestrictions($this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms))
 | 
			
		||||
            ->paginate($count)->appends($paginationAppends);
 | 
			
		||||
 | 
			
		||||
        // Add highlights to page text.
 | 
			
		||||
| 
						 | 
				
			
			@ -578,13 +578,13 @@ class PageRepo extends EntityRepo
 | 
			
		|||
     * Destroy a given page along with its dependencies.
 | 
			
		||||
     * @param $page
 | 
			
		||||
     */
 | 
			
		||||
    public function destroy($page)
 | 
			
		||||
    public function destroy(Page $page)
 | 
			
		||||
    {
 | 
			
		||||
        Activity::removeEntity($page);
 | 
			
		||||
        $page->views()->delete();
 | 
			
		||||
        $page->revisions()->delete();
 | 
			
		||||
        $page->restrictions()->delete();
 | 
			
		||||
        $this->restrictionService->deleteEntityPermissionsForEntity($page);
 | 
			
		||||
        $page->permissions()->delete();
 | 
			
		||||
        $this->permissionService->deleteJointPermissionsForEntity($page);
 | 
			
		||||
        $page->delete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,9 +2,9 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
use BookStack\Exceptions\PermissionsException;
 | 
			
		||||
use BookStack\Permission;
 | 
			
		||||
use BookStack\RolePermission;
 | 
			
		||||
use BookStack\Role;
 | 
			
		||||
use BookStack\Services\RestrictionService;
 | 
			
		||||
use BookStack\Services\PermissionService;
 | 
			
		||||
use Setting;
 | 
			
		||||
 | 
			
		||||
class PermissionsRepo
 | 
			
		||||
| 
						 | 
				
			
			@ -12,21 +12,21 @@ class PermissionsRepo
 | 
			
		|||
 | 
			
		||||
    protected $permission;
 | 
			
		||||
    protected $role;
 | 
			
		||||
    protected $restrictionService;
 | 
			
		||||
    protected $permissionService;
 | 
			
		||||
 | 
			
		||||
    protected $systemRoles = ['admin', 'public'];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * PermissionsRepo constructor.
 | 
			
		||||
     * @param Permission $permission
 | 
			
		||||
     * @param RolePermission $permission
 | 
			
		||||
     * @param Role $role
 | 
			
		||||
     * @param RestrictionService $restrictionService
 | 
			
		||||
     * @param PermissionService $permissionService
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Permission $permission, Role $role, RestrictionService $restrictionService)
 | 
			
		||||
    public function __construct(RolePermission $permission, Role $role, PermissionService $permissionService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->permission = $permission;
 | 
			
		||||
        $this->role = $role;
 | 
			
		||||
        $this->restrictionService = $restrictionService;
 | 
			
		||||
        $this->permissionService = $permissionService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ class PermissionsRepo
 | 
			
		|||
 | 
			
		||||
        $permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
 | 
			
		||||
        $this->assignRolePermissions($role, $permissions);
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionForRole($role);
 | 
			
		||||
        $this->permissionService->buildJointPermissionForRole($role);
 | 
			
		||||
        return $role;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ class PermissionsRepo
 | 
			
		|||
 | 
			
		||||
        $role->fill($roleData);
 | 
			
		||||
        $role->save();
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionForRole($role);
 | 
			
		||||
        $this->permissionService->buildJointPermissionForRole($role);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ class PermissionsRepo
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->restrictionService->deleteEntityPermissionsForRole($role);
 | 
			
		||||
        $this->permissionService->deleteJointPermissionsForRole($role);
 | 
			
		||||
        $role->delete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Restriction extends Model
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    protected $fillable = ['role_id', 'action'];
 | 
			
		||||
    public $timestamps = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all this restriction's attached entity.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
 | 
			
		||||
     */
 | 
			
		||||
    public function restrictable()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->morphTo();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								app/Role.php
								
								
								
								
							
							
						
						
									
										22
									
								
								app/Role.php
								
								
								
								
							| 
						 | 
				
			
			@ -11,24 +11,24 @@ class Role extends Model
 | 
			
		|||
     */
 | 
			
		||||
    public function users()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsToMany('BookStack\User');
 | 
			
		||||
        return $this->belongsToMany(User::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all related entity permissions.
 | 
			
		||||
     * Get all related JointPermissions.
 | 
			
		||||
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
 | 
			
		||||
     */
 | 
			
		||||
    public function entityPermissions()
 | 
			
		||||
    public function jointPermissions()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany(EntityPermission::class);
 | 
			
		||||
        return $this->hasMany(JointPermission::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The permissions that belong to the role.
 | 
			
		||||
     * The RolePermissions that belong to the role.
 | 
			
		||||
     */
 | 
			
		||||
    public function permissions()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsToMany('BookStack\Permission');
 | 
			
		||||
        return $this->belongsToMany(RolePermission::class, 'permission_role', 'role_id', 'permission_id');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -47,18 +47,18 @@ class Role extends Model
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a permission to this role.
 | 
			
		||||
     * @param Permission $permission
 | 
			
		||||
     * @param RolePermission $permission
 | 
			
		||||
     */
 | 
			
		||||
    public function attachPermission(Permission $permission)
 | 
			
		||||
    public function attachPermission(RolePermission $permission)
 | 
			
		||||
    {
 | 
			
		||||
        $this->permissions()->attach($permission->id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Detach a single permission from this role.
 | 
			
		||||
     * @param Permission $permission
 | 
			
		||||
     * @param RolePermission $permission
 | 
			
		||||
     */
 | 
			
		||||
    public function detachPermission(Permission $permission)
 | 
			
		||||
    public function detachPermission(RolePermission $permission)
 | 
			
		||||
    {
 | 
			
		||||
        $this->permissions()->detach($permission->id);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ class Role extends Model
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GEt all visible roles
 | 
			
		||||
     * Get all visible roles
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public static function visible()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,14 @@
 | 
			
		|||
<?php namespace BookStack;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Permission extends Model
 | 
			
		||||
class RolePermission extends Model
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The roles that belong to the permission.
 | 
			
		||||
     */
 | 
			
		||||
    public function roles()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsToMany('BookStack\Role');
 | 
			
		||||
        return $this->belongsToMany(Role::class, 'permission_role','permission_id', 'role_id');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -8,17 +8,17 @@ class ActivityService
 | 
			
		|||
{
 | 
			
		||||
    protected $activity;
 | 
			
		||||
    protected $user;
 | 
			
		||||
    protected $restrictionService;
 | 
			
		||||
    protected $permissionService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ActivityService constructor.
 | 
			
		||||
     * @param Activity $activity
 | 
			
		||||
     * @param RestrictionService $restrictionService
 | 
			
		||||
     * @param PermissionService $permissionService
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Activity $activity, RestrictionService $restrictionService)
 | 
			
		||||
    public function __construct(Activity $activity, PermissionService $permissionService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->activity = $activity;
 | 
			
		||||
        $this->restrictionService = $restrictionService;
 | 
			
		||||
        $this->permissionService = $permissionService;
 | 
			
		||||
        $this->user = auth()->user();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ class ActivityService
 | 
			
		|||
     */
 | 
			
		||||
    public function latest($count = 20, $page = 0)
 | 
			
		||||
    {
 | 
			
		||||
        $activityList = $this->restrictionService
 | 
			
		||||
        $activityList = $this->permissionService
 | 
			
		||||
            ->filterRestrictedEntityRelations($this->activity, 'activities', 'entity_id', 'entity_type')
 | 
			
		||||
            ->orderBy('created_at', 'desc')->skip($count * $page)->take($count)->get();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ class ActivityService
 | 
			
		|||
                ->where('entity_id', '=', $entity->id);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $activity = $this->restrictionService
 | 
			
		||||
        $activity = $this->permissionService
 | 
			
		||||
            ->filterRestrictedEntityRelations($query, 'activities', 'entity_id', 'entity_type')
 | 
			
		||||
            ->orderBy('created_at', 'desc')->skip($count * $page)->take($count)->get();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ class ActivityService
 | 
			
		|||
     */
 | 
			
		||||
    public function userActivity($user, $count = 20, $page = 0)
 | 
			
		||||
    {
 | 
			
		||||
        $activityList = $this->restrictionService
 | 
			
		||||
        $activityList = $this->permissionService
 | 
			
		||||
            ->filterRestrictedEntityRelations($this->activity, 'activities', 'entity_id', 'entity_type')
 | 
			
		||||
            ->orderBy('created_at', 'desc')->where('user_id', '=', $user->id)->skip($count * $page)->take($count)->get();
 | 
			
		||||
        return $this->filterSimilar($activityList);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,13 +3,13 @@
 | 
			
		|||
use BookStack\Book;
 | 
			
		||||
use BookStack\Chapter;
 | 
			
		||||
use BookStack\Entity;
 | 
			
		||||
use BookStack\EntityPermission;
 | 
			
		||||
use BookStack\JointPermission;
 | 
			
		||||
use BookStack\Page;
 | 
			
		||||
use BookStack\Role;
 | 
			
		||||
use BookStack\User;
 | 
			
		||||
use Illuminate\Database\Eloquent\Collection;
 | 
			
		||||
 | 
			
		||||
class RestrictionService
 | 
			
		||||
class PermissionService
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    protected $userRoles;
 | 
			
		||||
| 
						 | 
				
			
			@ -21,18 +21,18 @@ class RestrictionService
 | 
			
		|||
    public $chapter;
 | 
			
		||||
    public $page;
 | 
			
		||||
 | 
			
		||||
    protected $entityPermission;
 | 
			
		||||
    protected $jointPermission;
 | 
			
		||||
    protected $role;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * RestrictionService constructor.
 | 
			
		||||
     * @param EntityPermission $entityPermission
 | 
			
		||||
     * PermissionService constructor.
 | 
			
		||||
     * @param JointPermission $jointPermission
 | 
			
		||||
     * @param Book $book
 | 
			
		||||
     * @param Chapter $chapter
 | 
			
		||||
     * @param Page $page
 | 
			
		||||
     * @param Role $role
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role)
 | 
			
		||||
    public function __construct(JointPermission $jointPermission, Book $book, Chapter $chapter, Page $page, Role $role)
 | 
			
		||||
    {
 | 
			
		||||
        $this->currentUser = auth()->user();
 | 
			
		||||
        $userSet = $this->currentUser !== null;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ class RestrictionService
 | 
			
		|||
        $this->isAdmin = $userSet ? $this->currentUser->hasRole('admin') : false;
 | 
			
		||||
        if (!$userSet) $this->currentUser = new User();
 | 
			
		||||
 | 
			
		||||
        $this->entityPermission = $entityPermission;
 | 
			
		||||
        $this->jointPermission = $jointPermission;
 | 
			
		||||
        $this->role = $role;
 | 
			
		||||
        $this->book = $book;
 | 
			
		||||
        $this->chapter = $chapter;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,36 +72,36 @@ class RestrictionService
 | 
			
		|||
    /**
 | 
			
		||||
     * Re-generate all entity permission from scratch.
 | 
			
		||||
     */
 | 
			
		||||
    public function buildEntityPermissions()
 | 
			
		||||
    public function buildJointPermissions()
 | 
			
		||||
    {
 | 
			
		||||
        $this->entityPermission->truncate();
 | 
			
		||||
        $this->jointPermission->truncate();
 | 
			
		||||
 | 
			
		||||
        // Get all roles (Should be the most limited dimension)
 | 
			
		||||
        $roles = $this->role->with('permissions')->get();
 | 
			
		||||
 | 
			
		||||
        // Chunk through all books
 | 
			
		||||
        $this->book->with('restrictions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($books, $roles);
 | 
			
		||||
        $this->book->with('permissions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($books, $roles);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Chunk through all chapters
 | 
			
		||||
        $this->chapter->with('book', 'restrictions')->chunk(500, function ($chapters) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($chapters, $roles);
 | 
			
		||||
        $this->chapter->with('book', 'permissions')->chunk(500, function ($chapters) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($chapters, $roles);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Chunk through all pages
 | 
			
		||||
        $this->page->with('book', 'chapter', 'restrictions')->chunk(500, function ($pages) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($pages, $roles);
 | 
			
		||||
        $this->page->with('book', 'chapter', 'permissions')->chunk(500, function ($pages) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($pages, $roles);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create the entity permissions for a particular entity.
 | 
			
		||||
     * Create the entity jointPermissions for a particular entity.
 | 
			
		||||
     * @param Entity $entity
 | 
			
		||||
     */
 | 
			
		||||
    public function buildEntityPermissionsForEntity(Entity $entity)
 | 
			
		||||
    public function buildJointPermissionsForEntity(Entity $entity)
 | 
			
		||||
    {
 | 
			
		||||
        $roles = $this->role->with('permissions')->get();
 | 
			
		||||
        $roles = $this->role->with('jointPermissions')->get();
 | 
			
		||||
        $entities = collect([$entity]);
 | 
			
		||||
 | 
			
		||||
        if ($entity->isA('book')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -111,92 +111,92 @@ class RestrictionService
 | 
			
		|||
            $entities = $entities->merge($entity->pages);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->deleteManyEntityPermissionsForEntities($entities);
 | 
			
		||||
        $this->createManyEntityPermissions($entities, $roles);
 | 
			
		||||
        $this->deleteManyJointPermissionsForEntities($entities);
 | 
			
		||||
        $this->createManyJointPermissions($entities, $roles);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build the entity permissions for a particular role.
 | 
			
		||||
     * Build the entity jointPermissions for a particular role.
 | 
			
		||||
     * @param Role $role
 | 
			
		||||
     */
 | 
			
		||||
    public function buildEntityPermissionForRole(Role $role)
 | 
			
		||||
    public function buildJointPermissionForRole(Role $role)
 | 
			
		||||
    {
 | 
			
		||||
        $roles = collect([$role]);
 | 
			
		||||
 | 
			
		||||
        $this->deleteManyEntityPermissionsForRoles($roles);
 | 
			
		||||
        $this->deleteManyJointPermissionsForRoles($roles);
 | 
			
		||||
 | 
			
		||||
        // Chunk through all books
 | 
			
		||||
        $this->book->with('restrictions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($books, $roles);
 | 
			
		||||
        $this->book->with('permissions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($books, $roles);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Chunk through all chapters
 | 
			
		||||
        $this->chapter->with('book', 'restrictions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($books, $roles);
 | 
			
		||||
        $this->chapter->with('book', 'permissions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($books, $roles);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Chunk through all pages
 | 
			
		||||
        $this->page->with('book', 'chapter', 'restrictions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyEntityPermissions($books, $roles);
 | 
			
		||||
        $this->page->with('book', 'chapter', 'permissions')->chunk(500, function ($books) use ($roles) {
 | 
			
		||||
            $this->createManyJointPermissions($books, $roles);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete the entity permissions attached to a particular role.
 | 
			
		||||
     * Delete the entity jointPermissions attached to a particular role.
 | 
			
		||||
     * @param Role $role
 | 
			
		||||
     */
 | 
			
		||||
    public function deleteEntityPermissionsForRole(Role $role)
 | 
			
		||||
    public function deleteJointPermissionsForRole(Role $role)
 | 
			
		||||
    {
 | 
			
		||||
        $this->deleteManyEntityPermissionsForRoles([$role]);
 | 
			
		||||
        $this->deleteManyJointPermissionsForRoles([$role]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete all of the entity permissions for a list of entities.
 | 
			
		||||
     * Delete all of the entity jointPermissions for a list of entities.
 | 
			
		||||
     * @param Role[] $roles
 | 
			
		||||
     */
 | 
			
		||||
    protected function deleteManyEntityPermissionsForRoles($roles)
 | 
			
		||||
    protected function deleteManyJointPermissionsForRoles($roles)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($roles as $role) {
 | 
			
		||||
            $role->entityPermissions()->delete();
 | 
			
		||||
            $role->jointPermissions()->delete();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete the entity permissions for a particular entity.
 | 
			
		||||
     * Delete the entity jointPermissions for a particular entity.
 | 
			
		||||
     * @param Entity $entity
 | 
			
		||||
     */
 | 
			
		||||
    public function deleteEntityPermissionsForEntity(Entity $entity)
 | 
			
		||||
    public function deleteJointPermissionsForEntity(Entity $entity)
 | 
			
		||||
    {
 | 
			
		||||
        $this->deleteManyEntityPermissionsForEntities([$entity]);
 | 
			
		||||
        $this->deleteManyJointPermissionsForEntities([$entity]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete all of the entity permissions for a list of entities.
 | 
			
		||||
     * Delete all of the entity jointPermissions for a list of entities.
 | 
			
		||||
     * @param Entity[] $entities
 | 
			
		||||
     */
 | 
			
		||||
    protected function deleteManyEntityPermissionsForEntities($entities)
 | 
			
		||||
    protected function deleteManyJointPermissionsForEntities($entities)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            $entity->permissions()->delete();
 | 
			
		||||
            $entity->jointPermissions()->delete();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create & Save entity permissions for many entities and permissions.
 | 
			
		||||
     * Create & Save entity jointPermissions for many entities and jointPermissions.
 | 
			
		||||
     * @param Collection $entities
 | 
			
		||||
     * @param Collection $roles
 | 
			
		||||
     */
 | 
			
		||||
    protected function createManyEntityPermissions($entities, $roles)
 | 
			
		||||
    protected function createManyJointPermissions($entities, $roles)
 | 
			
		||||
    {
 | 
			
		||||
        $entityPermissions = [];
 | 
			
		||||
        $jointPermissions = [];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($roles as $role) {
 | 
			
		||||
                foreach ($this->getActions($entity) as $action) {
 | 
			
		||||
                    $entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action);
 | 
			
		||||
                    $jointPermissions[] = $this->createJointPermissionData($entity, $role, $action);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $this->entityPermission->insert($entityPermissions);
 | 
			
		||||
        $this->jointPermission->insert($jointPermissions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ class RestrictionService
 | 
			
		|||
     * @param $action
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    protected function createEntityPermissionData(Entity $entity, Role $role, $action)
 | 
			
		||||
    protected function createJointPermissionData(Entity $entity, Role $role, $action)
 | 
			
		||||
    {
 | 
			
		||||
        $permissionPrefix = (strpos($action, '-') === false ? ($entity->getType() . '-') : '') . $action;
 | 
			
		||||
        $roleHasPermission = $role->hasPermission($permissionPrefix . '-all');
 | 
			
		||||
| 
						 | 
				
			
			@ -238,10 +238,10 @@ class RestrictionService
 | 
			
		|||
        if ($entity->isA('book')) {
 | 
			
		||||
 | 
			
		||||
            if (!$entity->restricted) {
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
 | 
			
		||||
            } else {
 | 
			
		||||
                $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } elseif ($entity->isA('chapter')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -249,12 +249,12 @@ class RestrictionService
 | 
			
		|||
            if (!$entity->restricted) {
 | 
			
		||||
                $hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $restrictionAction);
 | 
			
		||||
                $hasPermissiveAccessToBook = !$entity->book->restricted;
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action,
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action,
 | 
			
		||||
                    ($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)),
 | 
			
		||||
                    ($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook)));
 | 
			
		||||
            } else {
 | 
			
		||||
                $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } elseif ($entity->isA('page')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,20 +269,20 @@ class RestrictionService
 | 
			
		|||
                $hasExplicitAccessToParents = $acknowledgeChapter ? $hasExplicitAccessToChapter : $hasExplicitAccessToBook;
 | 
			
		||||
                $hasPermissiveAccessToParents = $acknowledgeChapter ? $hasPermissiveAccessToChapter : $hasPermissiveAccessToBook;
 | 
			
		||||
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action,
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action,
 | 
			
		||||
                    ($hasExplicitAccessToParents || ($roleHasPermission && $hasPermissiveAccessToParents)),
 | 
			
		||||
                    ($hasExplicitAccessToParents || ($roleHasPermissionOwn && $hasPermissiveAccessToParents))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                $hasAccess = $entity->hasRestriction($role->id, $action);
 | 
			
		||||
                return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
                return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an array of data with the information of an entity permissions.
 | 
			
		||||
     * Create an array of data with the information of an entity jointPermissions.
 | 
			
		||||
     * Used to build data for bulk insertion.
 | 
			
		||||
     * @param Entity $entity
 | 
			
		||||
     * @param Role $role
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +291,7 @@ class RestrictionService
 | 
			
		|||
     * @param $permissionOwn
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    protected function createEntityPermissionDataArray(Entity $entity, Role $role, $action, $permissionAll, $permissionOwn)
 | 
			
		||||
    protected function createJointPermissionDataArray(Entity $entity, Role $role, $action, $permissionAll, $permissionOwn)
 | 
			
		||||
    {
 | 
			
		||||
        $entityClass = get_class($entity);
 | 
			
		||||
        return [
 | 
			
		||||
| 
						 | 
				
			
			@ -320,10 +320,10 @@ class RestrictionService
 | 
			
		|||
        $action = end($explodedPermission);
 | 
			
		||||
        $this->currentAction = $action;
 | 
			
		||||
 | 
			
		||||
        $nonEntityPermissions = ['restrictions'];
 | 
			
		||||
        $nonJointPermissions = ['restrictions'];
 | 
			
		||||
 | 
			
		||||
        // Handle non entity specific permissions
 | 
			
		||||
        if (in_array($explodedPermission[0], $nonEntityPermissions)) {
 | 
			
		||||
        // Handle non entity specific jointPermissions
 | 
			
		||||
        if (in_array($explodedPermission[0], $nonJointPermissions)) {
 | 
			
		||||
            $allPermission = $this->currentUser && $this->currentUser->can($permission . '-all');
 | 
			
		||||
            $ownPermission = $this->currentUser && $this->currentUser->can($permission . '-own');
 | 
			
		||||
            $this->currentAction = 'view';
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ class RestrictionService
 | 
			
		|||
            return ($allPermission || ($isOwner && $ownPermission));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Handle abnormal create permissions
 | 
			
		||||
        // Handle abnormal create jointPermissions
 | 
			
		||||
        if ($action === 'create') {
 | 
			
		||||
            $this->currentAction = $permission;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -368,7 +368,7 @@ class RestrictionService
 | 
			
		|||
    protected function entityRestrictionQuery($query)
 | 
			
		||||
    {
 | 
			
		||||
        return $query->where(function ($parentQuery) {
 | 
			
		||||
            $parentQuery->whereHas('permissions', function ($permissionQuery) {
 | 
			
		||||
            $parentQuery->whereHas('jointPermissions', function ($permissionQuery) {
 | 
			
		||||
                $permissionQuery->whereIn('role_id', $this->getRoles())
 | 
			
		||||
                    ->where('action', '=', $this->currentAction)
 | 
			
		||||
                    ->where(function ($query) {
 | 
			
		||||
| 
						 | 
				
			
			@ -447,9 +447,9 @@ class RestrictionService
 | 
			
		|||
 | 
			
		||||
        return $query->where(function ($query) use ($tableDetails) {
 | 
			
		||||
            $query->whereExists(function ($permissionQuery) use (&$tableDetails) {
 | 
			
		||||
                $permissionQuery->select('id')->from('entity_permissions')
 | 
			
		||||
                    ->whereRaw('entity_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
 | 
			
		||||
                    ->whereRaw('entity_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
 | 
			
		||||
                $permissionQuery->select('id')->from('joint_permissions')
 | 
			
		||||
                    ->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
 | 
			
		||||
                    ->whereRaw('joint_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
 | 
			
		||||
                    ->where('action', '=', $this->currentAction)
 | 
			
		||||
                    ->whereIn('role_id', $this->getRoles())
 | 
			
		||||
                    ->where(function ($query) {
 | 
			
		||||
| 
						 | 
				
			
			@ -479,8 +479,8 @@ class RestrictionService
 | 
			
		|||
        return $query->where(function ($query) use ($tableDetails) {
 | 
			
		||||
            $query->where(function ($query) use (&$tableDetails) {
 | 
			
		||||
                $query->whereExists(function ($permissionQuery) use (&$tableDetails) {
 | 
			
		||||
                    $permissionQuery->select('id')->from('entity_permissions')
 | 
			
		||||
                        ->whereRaw('entity_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
 | 
			
		||||
                    $permissionQuery->select('id')->from('joint_permissions')
 | 
			
		||||
                        ->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
 | 
			
		||||
                        ->where('entity_type', '=', 'Bookstack\\Page')
 | 
			
		||||
                        ->where('action', '=', $this->currentAction)
 | 
			
		||||
                        ->whereIn('role_id', $this->getRoles())
 | 
			
		||||
| 
						 | 
				
			
			@ -8,18 +8,18 @@ class ViewService
 | 
			
		|||
 | 
			
		||||
    protected $view;
 | 
			
		||||
    protected $user;
 | 
			
		||||
    protected $restrictionService;
 | 
			
		||||
    protected $permissionService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ViewService constructor.
 | 
			
		||||
     * @param View $view
 | 
			
		||||
     * @param RestrictionService $restrictionService
 | 
			
		||||
     * @param PermissionService $permissionService
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(View $view, RestrictionService $restrictionService)
 | 
			
		||||
    public function __construct(View $view, PermissionService $permissionService)
 | 
			
		||||
    {
 | 
			
		||||
        $this->view = $view;
 | 
			
		||||
        $this->user = auth()->user();
 | 
			
		||||
        $this->restrictionService = $restrictionService;
 | 
			
		||||
        $this->permissionService = $permissionService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ class ViewService
 | 
			
		|||
    public function getPopular($count = 10, $page = 0, $filterModel = false)
 | 
			
		||||
    {
 | 
			
		||||
        $skipCount = $count * $page;
 | 
			
		||||
        $query = $this->restrictionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type')
 | 
			
		||||
        $query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type')
 | 
			
		||||
            ->select('*', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
 | 
			
		||||
            ->groupBy('viewable_id', 'viewable_type')
 | 
			
		||||
            ->orderBy('view_count', 'desc');
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ class ViewService
 | 
			
		|||
    {
 | 
			
		||||
        if ($this->user === null) return collect();
 | 
			
		||||
 | 
			
		||||
        $query = $this->restrictionService
 | 
			
		||||
        $query = $this->permissionService
 | 
			
		||||
            ->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
 | 
			
		||||
 | 
			
		||||
        if ($filterModel) $query = $query->where('viewable_type', '=', get_class($filterModel));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,6 @@ class SocialAccount extends Model
 | 
			
		|||
 | 
			
		||||
    public function user()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\User');
 | 
			
		||||
        return $this->belongsTo(User::class);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
 | 
			
		|||
     */
 | 
			
		||||
    public function roles()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsToMany('BookStack\Role');
 | 
			
		||||
        return $this->belongsToMany(Role::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
 | 
			
		|||
     */
 | 
			
		||||
    public function socialAccounts()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany('BookStack\SocialAccount');
 | 
			
		||||
        return $this->hasMany(SocialAccount::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
 | 
			
		|||
     */
 | 
			
		||||
    public function avatar()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo('BookStack\Image', 'image_id');
 | 
			
		||||
        return $this->belongsTo(Image::class, 'image_id');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ if (!function_exists('versioned_asset')) {
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if the current user has a permission.
 | 
			
		||||
 * If an ownable element is passed in the permissions are checked against
 | 
			
		||||
 * If an ownable element is passed in the jointPermissions are checked against
 | 
			
		||||
 * that particular item.
 | 
			
		||||
 * @param $permission
 | 
			
		||||
 * @param \BookStack\Ownable $ownable
 | 
			
		||||
| 
						 | 
				
			
			@ -44,8 +44,8 @@ function userCan($permission, \BookStack\Ownable $ownable = null)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Check permission on ownable item
 | 
			
		||||
    $restrictionService = app('BookStack\Services\RestrictionService');
 | 
			
		||||
    return $restrictionService->checkEntityUserAccess($ownable, $permission);
 | 
			
		||||
    $permissionService = app('BookStack\Services\PermissionService');
 | 
			
		||||
    return $permissionService->checkEntityUserAccess($ownable, $permission);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,10 +21,13 @@ class CreateUsersTable extends Migration
 | 
			
		|||
            $table->nullableTimestamps();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        \BookStack\User::forceCreate([
 | 
			
		||||
        // Create the initial admin user
 | 
			
		||||
        DB::table('users')->insert([
 | 
			
		||||
            'name' => 'Admin',
 | 
			
		||||
            'email' => 'admin@admin.com',
 | 
			
		||||
            'password' => bcrypt('password')
 | 
			
		||||
            'password' => bcrypt('password'),
 | 
			
		||||
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
            'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,35 +68,44 @@ class AddRolesAndPermissions extends Migration
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
        // Create default roles
 | 
			
		||||
        $admin = new \BookStack\Role();
 | 
			
		||||
        $admin->name = 'admin';
 | 
			
		||||
        $admin->display_name = 'Admin';
 | 
			
		||||
        $admin->description = 'Administrator of the whole application';
 | 
			
		||||
        $admin->save();
 | 
			
		||||
        $adminId = DB::table('roles')->insertGetId([
 | 
			
		||||
            'name' => 'admin',
 | 
			
		||||
            'display_name' => 'Admin',
 | 
			
		||||
            'description' => 'Administrator of the whole application',
 | 
			
		||||
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
            'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
        ]);
 | 
			
		||||
        $editorId = DB::table('roles')->insertGetId([
 | 
			
		||||
            'name' => 'editor',
 | 
			
		||||
            'display_name' => 'Editor',
 | 
			
		||||
            'description' => 'User can edit Books, Chapters & Pages',
 | 
			
		||||
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
            'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
        ]);
 | 
			
		||||
        $viewerId = DB::table('roles')->insertGetId([
 | 
			
		||||
            'name' => 'viewer',
 | 
			
		||||
            'display_name' => 'Viewer',
 | 
			
		||||
            'description' => 'User can view books & their content behind authentication',
 | 
			
		||||
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
            'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $editor = new \BookStack\Role();
 | 
			
		||||
        $editor->name = 'editor';
 | 
			
		||||
        $editor->display_name = 'Editor';
 | 
			
		||||
        $editor->description = 'User can edit Books, Chapters & Pages';
 | 
			
		||||
        $editor->save();
 | 
			
		||||
 | 
			
		||||
        $viewer = new \BookStack\Role();
 | 
			
		||||
        $viewer->name = 'viewer';
 | 
			
		||||
        $viewer->display_name = 'Viewer';
 | 
			
		||||
        $viewer->description = 'User can view books & their content behind authentication';
 | 
			
		||||
        $viewer->save();
 | 
			
		||||
 | 
			
		||||
        // Create default CRUD permissions and allocate to admins and editors
 | 
			
		||||
        $entities = ['Book', 'Page', 'Chapter', 'Image'];
 | 
			
		||||
        $ops = ['Create', 'Update', 'Delete'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower($op);
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity . 's';
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                $admin->attachPermission($newPermission);
 | 
			
		||||
                $editor->attachPermission($newPermission);
 | 
			
		||||
                $newPermId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower($op),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity . 's',
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    ['permission_id' => $newPermId, 'role_id' => $adminId],
 | 
			
		||||
                    ['permission_id' => $newPermId, 'role_id' => $editorId]
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -105,19 +114,27 @@ class AddRolesAndPermissions extends Migration
 | 
			
		|||
        $ops = ['Create', 'Update', 'Delete'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower($op);
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity;
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                $admin->attachPermission($newPermission);
 | 
			
		||||
                $newPermId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower($op),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity,
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    'permission_id' => $newPermId,
 | 
			
		||||
                    'role_id' => $adminId
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set all current users as admins
 | 
			
		||||
        // (At this point only the initially create user should be an admin)
 | 
			
		||||
        $users = \BookStack\User::all();
 | 
			
		||||
        $users = DB::table('users')->get();
 | 
			
		||||
        foreach ($users as $user) {
 | 
			
		||||
            $user->attachRole($admin);
 | 
			
		||||
            DB::table('role_user')->insert([
 | 
			
		||||
                'role_id' => $adminId,
 | 
			
		||||
                'user_id' => $user->id
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,29 +13,31 @@ class UpdatePermissionsAndRoles extends Migration
 | 
			
		|||
    public function up()
 | 
			
		||||
    {
 | 
			
		||||
        // Get roles with permissions we need to change
 | 
			
		||||
        $adminRole = \BookStack\Role::getRole('admin');
 | 
			
		||||
        $editorRole = \BookStack\Role::getRole('editor');
 | 
			
		||||
        $adminRoleId = DB::table('roles')->where('name', '=', 'admin')->first()->id;
 | 
			
		||||
        $editorRole = DB::table('roles')->where('name', '=', 'editor')->first();
 | 
			
		||||
 | 
			
		||||
        // Delete old permissions
 | 
			
		||||
        $permissions = \BookStack\Permission::all();
 | 
			
		||||
        $permissions->each(function ($permission) {
 | 
			
		||||
            $permission->delete();
 | 
			
		||||
        });
 | 
			
		||||
        $permissions = DB::table('permissions')->delete();
 | 
			
		||||
 | 
			
		||||
        // Create & attach new admin permissions
 | 
			
		||||
        $permissionsToCreate = [
 | 
			
		||||
            'settings-manage' => 'Manage Settings',
 | 
			
		||||
            'users-manage' => 'Manage Users',
 | 
			
		||||
            'user-roles-manage' => 'Manage Roles & Permissions',
 | 
			
		||||
            'restrictions-manage-all' => 'Manage All Entity Restrictions',
 | 
			
		||||
            'restrictions-manage-own' => 'Manage Entity Restrictions On Own Content'
 | 
			
		||||
            'restrictions-manage-all' => 'Manage All Entity Permissions',
 | 
			
		||||
            'restrictions-manage-own' => 'Manage Entity Permissions On Own Content'
 | 
			
		||||
        ];
 | 
			
		||||
        foreach ($permissionsToCreate as $name => $displayName) {
 | 
			
		||||
            $newPermission = new \BookStack\Permission();
 | 
			
		||||
            $newPermission->name = $name;
 | 
			
		||||
            $newPermission->display_name = $displayName;
 | 
			
		||||
            $newPermission->save();
 | 
			
		||||
            $adminRole->attachPermission($newPermission);
 | 
			
		||||
            $permissionId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                'name' => $name,
 | 
			
		||||
                'display_name' => $displayName,
 | 
			
		||||
                'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
            ]);
 | 
			
		||||
            DB::table('permission_role')->insert([
 | 
			
		||||
                'role_id' => $adminRoleId,
 | 
			
		||||
                'permission_id' => $permissionId
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create & attach new entity permissions
 | 
			
		||||
| 
						 | 
				
			
			@ -43,12 +45,22 @@ class UpdatePermissionsAndRoles extends Migration
 | 
			
		|||
        $ops = ['Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity . 's';
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                $adminRole->attachPermission($newPermission);
 | 
			
		||||
                if ($editorRole !== null) $editorRole->attachPermission($newPermission);
 | 
			
		||||
                $permissionId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity . 's',
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    'role_id' => $adminRoleId,
 | 
			
		||||
                    'permission_id' => $permissionId
 | 
			
		||||
                ]);
 | 
			
		||||
                if ($editorRole !== null) {
 | 
			
		||||
                    DB::table('permission_role')->insert([
 | 
			
		||||
                        'role_id' => $editorRole->id,
 | 
			
		||||
                        'permission_id' => $permissionId
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,24 +74,26 @@ class UpdatePermissionsAndRoles extends Migration
 | 
			
		|||
    public function down()
 | 
			
		||||
    {
 | 
			
		||||
        // Get roles with permissions we need to change
 | 
			
		||||
        $adminRole = \BookStack\Role::getRole('admin');
 | 
			
		||||
        $adminRoleId = DB::table('roles')->where('name', '=', 'admin')->first()->id;
 | 
			
		||||
 | 
			
		||||
        // Delete old permissions
 | 
			
		||||
        $permissions = \BookStack\Permission::all();
 | 
			
		||||
        $permissions->each(function ($permission) {
 | 
			
		||||
            $permission->delete();
 | 
			
		||||
        });
 | 
			
		||||
        $permissions = DB::table('permissions')->delete();
 | 
			
		||||
 | 
			
		||||
        // Create default CRUD permissions and allocate to admins and editors
 | 
			
		||||
        $entities = ['Book', 'Page', 'Chapter', 'Image'];
 | 
			
		||||
        $ops = ['Create', 'Update', 'Delete'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower($op);
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity . 's';
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                $adminRole->attachPermission($newPermission);
 | 
			
		||||
                $permissionId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower($op),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity . 's',
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    'role_id' => $adminRoleId,
 | 
			
		||||
                    'permission_id' => $permissionId
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -88,11 +102,16 @@ class UpdatePermissionsAndRoles extends Migration
 | 
			
		|||
        $ops = ['Create', 'Update', 'Delete'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower($op);
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity;
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                $adminRole->attachPermission($newPermission);
 | 
			
		||||
                $permissionId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower($op),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity,
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    'role_id' => $adminRoleId,
 | 
			
		||||
                    'permission_id' => $permissionId
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,20 +12,25 @@ class AddViewPermissionsToRoles extends Migration
 | 
			
		|||
     */
 | 
			
		||||
    public function up()
 | 
			
		||||
    {
 | 
			
		||||
        $currentRoles = \BookStack\Role::all();
 | 
			
		||||
        $currentRoles = DB::table('roles')->get();
 | 
			
		||||
 | 
			
		||||
        // Create new view permissions
 | 
			
		||||
        // Create new view permission
 | 
			
		||||
        $entities = ['Book', 'Page', 'Chapter'];
 | 
			
		||||
        $ops = ['View All', 'View Own'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $newPermission = new \BookStack\Permission();
 | 
			
		||||
                $newPermission->name = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
 | 
			
		||||
                $newPermission->display_name = $op . ' ' . $entity . 's';
 | 
			
		||||
                $newPermission->save();
 | 
			
		||||
                // Assign view permissions to all current roles
 | 
			
		||||
                $permId = DB::table('permissions')->insertGetId([
 | 
			
		||||
                    'name' => strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)),
 | 
			
		||||
                    'display_name' => $op . ' ' . $entity . 's',
 | 
			
		||||
                    'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
                    'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
                ]);
 | 
			
		||||
                // Assign view permission to all current roles
 | 
			
		||||
                foreach ($currentRoles as $role) {
 | 
			
		||||
                    $role->attachPermission($newPermission);
 | 
			
		||||
                    DB::table('permission_role')->insert([
 | 
			
		||||
                        'role_id' => $role->id,
 | 
			
		||||
                        'permission_id' => $permId
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -38,17 +43,15 @@ class AddViewPermissionsToRoles extends Migration
 | 
			
		|||
     */
 | 
			
		||||
    public function down()
 | 
			
		||||
    {
 | 
			
		||||
        // Delete the new view permissions
 | 
			
		||||
        // Delete the new view permission
 | 
			
		||||
        $entities = ['Book', 'Page', 'Chapter'];
 | 
			
		||||
        $ops = ['View All', 'View Own'];
 | 
			
		||||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $permissionName = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
 | 
			
		||||
                $newPermission = \BookStack\Permission::where('name', '=', $permissionName)->first();
 | 
			
		||||
                foreach ($newPermission->roles as $role) {
 | 
			
		||||
                    $role->detachPermission($newPermission);
 | 
			
		||||
                }
 | 
			
		||||
                $newPermission->delete();
 | 
			
		||||
                $permission = DB::table('permissions')->where('name', '=', $permissionName)->first();
 | 
			
		||||
                DB::table('permission_role')->where('permission_id', '=', $permission->id)->delete();
 | 
			
		||||
                DB::table('permissions')->where('name', '=', $permissionName)->delete();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
 | 
			
		||||
class CreateEntityPermissionsTable extends Migration
 | 
			
		||||
class CreateJointPermissionsTable extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ class CreateEntityPermissionsTable extends Migration
 | 
			
		|||
     */
 | 
			
		||||
    public function up()
 | 
			
		||||
    {
 | 
			
		||||
        Schema::create('entity_permissions', function (Blueprint $table) {
 | 
			
		||||
        Schema::create('joint_permissions', function (Blueprint $table) {
 | 
			
		||||
            $table->increments('id');
 | 
			
		||||
            $table->integer('role_id');
 | 
			
		||||
            $table->string('entity_type');
 | 
			
		||||
| 
						 | 
				
			
			@ -37,18 +37,25 @@ class CreateEntityPermissionsTable extends Migration
 | 
			
		|||
            $table->index('system_name');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Schema::rename('permissions', 'role_permissions');
 | 
			
		||||
        Schema::rename('restrictions', 'entity_permissions');
 | 
			
		||||
 | 
			
		||||
        // Create the new public role
 | 
			
		||||
        $publicRole = new \BookStack\Role();
 | 
			
		||||
        $publicRole->name = 'public';
 | 
			
		||||
        $publicRole->display_name = 'Public';
 | 
			
		||||
        $publicRole->description = 'The role given to public visitors if allowed';
 | 
			
		||||
        $publicRole->system_name = 'public';
 | 
			
		||||
        $publicRole->hidden = true;
 | 
			
		||||
        $publicRoleData = [
 | 
			
		||||
            'name' => 'public',
 | 
			
		||||
            'display_name' => 'Public',
 | 
			
		||||
            'description' => 'The role given to public visitors if allowed',
 | 
			
		||||
            'system_name' => 'public',
 | 
			
		||||
            'hidden' => true,
 | 
			
		||||
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
 | 
			
		||||
            'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        // Ensure unique name
 | 
			
		||||
        while (\BookStack\Role::getRole($publicRole->name) !== null) {
 | 
			
		||||
            $publicRole->name = $publicRole->name . str_random(2);
 | 
			
		||||
        while (DB::table('roles')->where('name', '=', $publicRoleData['display_name'])->count() > 0) {
 | 
			
		||||
            $publicRoleData['display_name'] = $publicRoleData['display_name'] . str_random(2);
 | 
			
		||||
        }
 | 
			
		||||
        $publicRole->save();
 | 
			
		||||
        $publicRoleId = DB::table('roles')->insertGetId($publicRoleData);
 | 
			
		||||
 | 
			
		||||
        // Add new view permissions to public role
 | 
			
		||||
        $entities = ['Book', 'Page', 'Chapter'];
 | 
			
		||||
| 
						 | 
				
			
			@ -56,20 +63,21 @@ class CreateEntityPermissionsTable extends Migration
 | 
			
		|||
        foreach ($entities as $entity) {
 | 
			
		||||
            foreach ($ops as $op) {
 | 
			
		||||
                $name = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
 | 
			
		||||
                $permission = \BookStack\Permission::getByName($name);
 | 
			
		||||
                // Assign view permissions to public
 | 
			
		||||
                $publicRole->attachPermission($permission);
 | 
			
		||||
                $permission = DB::table('role_permissions')->where('name', '=', $name)->first();
 | 
			
		||||
                // Assign view permission to public
 | 
			
		||||
                DB::table('permission_role')->insert([
 | 
			
		||||
                    'permission_id' => $permission->id,
 | 
			
		||||
                    'role_id' => $publicRoleId
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Update admin role with system name
 | 
			
		||||
        $admin = \BookStack\Role::getRole('admin');
 | 
			
		||||
        $admin->system_name = 'admin';
 | 
			
		||||
        $admin->save();
 | 
			
		||||
        DB::table('roles')->where('name', '=', 'admin')->update(['system_name' => 'admin']);
 | 
			
		||||
 | 
			
		||||
        // Generate the new entity permissions
 | 
			
		||||
        $restrictionService = app(\BookStack\Services\RestrictionService::class);
 | 
			
		||||
        $restrictionService->buildEntityPermissions();
 | 
			
		||||
        // Generate the new entity jointPermissions
 | 
			
		||||
        $restrictionService = app(\BookStack\Services\PermissionService::class);
 | 
			
		||||
        $restrictionService->buildJointPermissions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -79,11 +87,13 @@ class CreateEntityPermissionsTable extends Migration
 | 
			
		|||
     */
 | 
			
		||||
    public function down()
 | 
			
		||||
    {
 | 
			
		||||
        Schema::drop('entity_permissions');
 | 
			
		||||
        Schema::drop('joint_permissions');
 | 
			
		||||
 | 
			
		||||
        Schema::rename('role_permissions', 'permissions');
 | 
			
		||||
        Schema::rename('entity_permissions', 'restrictions');
 | 
			
		||||
 | 
			
		||||
        // Delete the public role
 | 
			
		||||
        $public = \BookStack\Role::getSystemRole('public');
 | 
			
		||||
        $public->delete();
 | 
			
		||||
        DB::table('roles')->where('system_name', '=', 'public')->delete();
 | 
			
		||||
 | 
			
		||||
        Schema::table('roles', function (Blueprint $table) {
 | 
			
		||||
            $table->dropColumn('system_name');
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ class DummyContentSeeder extends Seeder
 | 
			
		|||
                $book->pages()->saveMany($pages);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        $restrictionService = app(\BookStack\Services\RestrictionService::class);
 | 
			
		||||
        $restrictionService->buildEntityPermissions();
 | 
			
		||||
        $restrictionService = app(\BookStack\Services\PermissionService::class);
 | 
			
		||||
        $restrictionService->buildJointPermissions();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
<input type="checkbox" name="permissions[{{ $permission }}]"
 | 
			
		||||
       @if(old('permissions.'.$permission, false)|| (!old('display_name', false) && (isset($role) && $role->hasPermission($permission)))) checked="checked" @endif
 | 
			
		||||
       @if(old('permissions'.$permission, false)|| (!old('display_name', false) && (isset($role) && $role->hasPermission($permission)))) checked="checked" @endif
 | 
			
		||||
       value="true">
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@
 | 
			
		|||
                <label>@include('settings/roles/checkbox', ['permission' => 'users-manage']) Manage users</label>
 | 
			
		||||
                <label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) Manage roles & role permissions</label>
 | 
			
		||||
                <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) Manage all Book, Chapter & Page permissions</label>
 | 
			
		||||
                <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-own']) Manage permissions on own Book, Chapter & Pages</label>
 | 
			
		||||
                <label>@include('settings/roles/checkbox', ['permission' => 'permissions']) Manage permissions on own Book, Chapter & Pages</label>
 | 
			
		||||
                <label>@include('settings/roles/checkbox', ['permission' => 'settings-manage']) Manage app settings</label>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ class RestrictionsTest extends TestCase
 | 
			
		|||
        parent::setUp();
 | 
			
		||||
        $this->user = $this->getNewUser();
 | 
			
		||||
        $this->viewer = $this->getViewer();
 | 
			
		||||
        $this->restrictionService = $this->app[\BookStack\Services\RestrictionService::class];
 | 
			
		||||
        $this->restrictionService = $this->app[\BookStack\Services\PermissionService::class];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getViewer()
 | 
			
		||||
| 
						 | 
				
			
			@ -23,30 +23,30 @@ class RestrictionsTest extends TestCase
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Manually set some restrictions on an entity.
 | 
			
		||||
     * Manually set some permissions on an entity.
 | 
			
		||||
     * @param \BookStack\Entity $entity
 | 
			
		||||
     * @param $actions
 | 
			
		||||
     */
 | 
			
		||||
    protected function setEntityRestrictions(\BookStack\Entity $entity, $actions)
 | 
			
		||||
    {
 | 
			
		||||
        $entity->restricted = true;
 | 
			
		||||
        $entity->restrictions()->delete();
 | 
			
		||||
        $entity->permissions()->delete();
 | 
			
		||||
        $role = $this->user->roles->first();
 | 
			
		||||
        $viewerRole = $this->viewer->roles->first();
 | 
			
		||||
        foreach ($actions as $action) {
 | 
			
		||||
            $entity->restrictions()->create([
 | 
			
		||||
            $entity->permissions()->create([
 | 
			
		||||
                'role_id' => $role->id,
 | 
			
		||||
                'action' => strtolower($action)
 | 
			
		||||
            ]);
 | 
			
		||||
            $entity->restrictions()->create([
 | 
			
		||||
            $entity->permissions()->create([
 | 
			
		||||
                'role_id' => $viewerRole->id,
 | 
			
		||||
                'action' => strtolower($action)
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
        $entity->save();
 | 
			
		||||
        $entity->load('restrictions');
 | 
			
		||||
        $this->restrictionService->buildEntityPermissionsForEntity($entity);
 | 
			
		||||
        $entity->load('permissions');
 | 
			
		||||
        $this->restrictionService->buildJointPermissionsForEntity($entity);
 | 
			
		||||
        $entity->load('jointPermissions');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function test_book_view_restriction()
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +348,7 @@ class RestrictionsTest extends TestCase
 | 
			
		|||
            ->check('restrictions[2][view]')
 | 
			
		||||
            ->press('Save Permissions')
 | 
			
		||||
            ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true])
 | 
			
		||||
            ->seeInDatabase('restrictions', [
 | 
			
		||||
            ->seeInDatabase('entity_permissions', [
 | 
			
		||||
                'restrictable_id' => $book->id,
 | 
			
		||||
                'restrictable_type' => 'BookStack\Book',
 | 
			
		||||
                'role_id' => '2',
 | 
			
		||||
| 
						 | 
				
			
			@ -365,7 +365,7 @@ class RestrictionsTest extends TestCase
 | 
			
		|||
            ->check('restrictions[2][update]')
 | 
			
		||||
            ->press('Save Permissions')
 | 
			
		||||
            ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true])
 | 
			
		||||
            ->seeInDatabase('restrictions', [
 | 
			
		||||
            ->seeInDatabase('entity_permissions', [
 | 
			
		||||
                'restrictable_id' => $chapter->id,
 | 
			
		||||
                'restrictable_type' => 'BookStack\Chapter',
 | 
			
		||||
                'role_id' => '2',
 | 
			
		||||
| 
						 | 
				
			
			@ -382,7 +382,7 @@ class RestrictionsTest extends TestCase
 | 
			
		|||
            ->check('restrictions[2][delete]')
 | 
			
		||||
            ->press('Save Permissions')
 | 
			
		||||
            ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true])
 | 
			
		||||
            ->seeInDatabase('restrictions', [
 | 
			
		||||
            ->seeInDatabase('entity_permissions', [
 | 
			
		||||
                'restrictable_id' => $page->id,
 | 
			
		||||
                'restrictable_type' => 'BookStack\Page',
 | 
			
		||||
                'role_id' => '2',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,8 +65,8 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
 | 
			
		|||
        $page = factory(BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]);
 | 
			
		||||
        $book->chapters()->saveMany([$chapter]);
 | 
			
		||||
        $chapter->pages()->saveMany([$page]);
 | 
			
		||||
        $restrictionService = $this->app[\BookStack\Services\RestrictionService::class];
 | 
			
		||||
        $restrictionService->buildEntityPermissionsForEntity($book);
 | 
			
		||||
        $restrictionService = $this->app[\BookStack\Services\PermissionService::class];
 | 
			
		||||
        $restrictionService->buildJointPermissionsForEntity($book);
 | 
			
		||||
        return [
 | 
			
		||||
            'book' => $book,
 | 
			
		||||
            'chapter' => $chapter,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue