diff --git a/app/Activity.php b/app/Activity.php
index 34daa2760..a1fe608f0 100644
--- a/app/Activity.php
+++ b/app/Activity.php
@@ -19,11 +19,7 @@ class Activity extends Model
*/
public function entity()
{
- if ($this->entity_id) {
- return $this->morphTo('entity')->first();
- } else {
- return false;
- }
+ return $this->morphTo('entity');
}
/**
diff --git a/app/Providers/CustomFacadeProvider.php b/app/Providers/CustomFacadeProvider.php
index 1df14a076..9b290039c 100644
--- a/app/Providers/CustomFacadeProvider.php
+++ b/app/Providers/CustomFacadeProvider.php
@@ -28,11 +28,17 @@ class CustomFacadeProvider extends ServiceProvider
public function register()
{
$this->app->bind('activity', function() {
- return new ActivityService($this->app->make('BookStack\Activity'));
+ return new ActivityService(
+ $this->app->make('BookStack\Activity'),
+ $this->app->make('BookStack\Services\RestrictionService')
+ );
});
$this->app->bind('views', function() {
- return new ViewService($this->app->make('BookStack\View'));
+ return new ViewService(
+ $this->app->make('BookStack\View'),
+ $this->app->make('BookStack\Services\RestrictionService')
+ );
});
$this->app->bind('setting', function() {
@@ -41,6 +47,7 @@ class CustomFacadeProvider extends ServiceProvider
$this->app->make('Illuminate\Contracts\Cache\Repository')
);
});
+
$this->app->bind('images', function() {
return new ImageService(
$this->app->make('Intervention\Image\ImageManager'),
diff --git a/app/Repos/BookRepo.php b/app/Repos/BookRepo.php
index dbf95623e..572030d43 100644
--- a/app/Repos/BookRepo.php
+++ b/app/Repos/BookRepo.php
@@ -1,6 +1,7 @@
book = $book;
$this->pageRepo = $pageRepo;
$this->chapterRepo = $chapterRepo;
+ $this->restrictionService = $restrictionService;
+ }
+
+ /**
+ * Base query for getting books.
+ * Takes into account any restrictions.
+ * @return mixed
+ */
+ private function bookQuery()
+ {
+ return $this->restrictionService->enforceBookRestrictions($this->book, 'view');
}
/**
@@ -32,7 +46,7 @@ class BookRepo
*/
public function getById($id)
{
- return $this->book->findOrFail($id);
+ return $this->bookQuery()->findOrFail($id);
}
/**
@@ -42,7 +56,7 @@ class BookRepo
*/
public function getAll($count = 10)
{
- $bookQuery = $this->book->orderBy('name', 'asc');
+ $bookQuery = $this->bookQuery()->orderBy('name', 'asc');
if (!$count) return $bookQuery->get();
return $bookQuery->take($count)->get();
}
@@ -54,7 +68,8 @@ class BookRepo
*/
public function getAllPaginated($count = 10)
{
- return $this->book->orderBy('name', 'asc')->paginate($count);
+ return $this->bookQuery()
+ ->orderBy('name', 'asc')->paginate($count);
}
@@ -65,7 +80,7 @@ class BookRepo
*/
public function getLatest($count = 10)
{
- return $this->book->orderBy('created_at', 'desc')->take($count)->get();
+ return $this->bookQuery()->orderBy('created_at', 'desc')->take($count)->get();
}
/**
@@ -76,6 +91,7 @@ class BookRepo
*/
public function getRecentlyViewed($count = 10, $page = 0)
{
+ // TODO restrict
return Views::getUserRecentlyViewed($count, $page, $this->book);
}
@@ -87,6 +103,7 @@ class BookRepo
*/
public function getPopular($count = 10, $page = 0)
{
+ // TODO - Restrict
return Views::getPopular($count, $page, $this->book);
}
@@ -97,7 +114,7 @@ class BookRepo
*/
public function getBySlug($slug)
{
- $book = $this->book->where('slug', '=', $slug)->first();
+ $book = $this->bookQuery()->where('slug', '=', $slug)->first();
if ($book === null) abort(404);
return $book;
}
@@ -109,7 +126,7 @@ class BookRepo
*/
public function exists($id)
{
- return $this->book->where('id', '=', $id)->exists();
+ return $this->bookQuery()->where('id', '=', $id)->exists();
}
/**
@@ -119,17 +136,7 @@ class BookRepo
*/
public function newFromInput($input)
{
- return $this->book->fill($input);
- }
-
- /**
- * Count the amount of books that have a specific slug.
- * @param $slug
- * @return mixed
- */
- public function countBySlug($slug)
- {
- return $this->book->where('slug', '=', $slug)->count();
+ return $this->bookQuery()->fill($input);
}
/**
@@ -202,8 +209,13 @@ class BookRepo
*/
public function getChildren(Book $book)
{
- $pages = $book->pages()->where('chapter_id', '=', 0)->get();
- $chapters = $book->chapters()->with('pages')->get();
+ $pageQuery = $book->pages()->where('chapter_id', '=', 0);
+ $this->restrictionService->enforcePageRestrictions($pageQuery, 'view');
+ $pages = $pageQuery->get();
+
+ $chapterQuery = $book->chapters()->with('pages');
+ $this->restrictionService->enforceChapterRestrictions($chapterQuery, 'view');
+ $chapters = $chapterQuery->get();
$children = $pages->merge($chapters);
$bookSlug = $book->slug;
$children->each(function ($child) use ($bookSlug) {
@@ -227,7 +239,7 @@ class BookRepo
public function getBySearch($term, $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
+ $books = $this->restrictionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
foreach ($books as $book) {
@@ -249,11 +261,11 @@ class BookRepo
$book->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
$book->restrictions()->delete();
if ($request->has('restrictions')) {
- foreach($request->get('restrictions') as $roleId => $restrictions) {
+ foreach ($request->get('restrictions') as $roleId => $restrictions) {
foreach ($restrictions as $action => $value) {
$book->restrictions()->create([
'role_id' => $roleId,
- 'action' => strtolower($action)
+ 'action' => strtolower($action)
]);
}
}
diff --git a/app/Repos/ChapterRepo.php b/app/Repos/ChapterRepo.php
index 7e3560f2b..90f2f8c54 100644
--- a/app/Repos/ChapterRepo.php
+++ b/app/Repos/ChapterRepo.php
@@ -2,6 +2,7 @@
use Activity;
+use BookStack\Services\RestrictionService;
use Illuminate\Support\Str;
use BookStack\Chapter;
@@ -9,14 +10,26 @@ class ChapterRepo
{
protected $chapter;
+ protected $restrictionService;
/**
* ChapterRepo constructor.
- * @param $chapter
+ * @param Chapter $chapter
+ * @param RestrictionService $restrictionService
*/
- public function __construct(Chapter $chapter)
+ public function __construct(Chapter $chapter, RestrictionService $restrictionService)
{
$this->chapter = $chapter;
+ $this->restrictionService = $restrictionService;
+ }
+
+ /**
+ * Base query for getting chapters, Takes restrictions into account.
+ * @return mixed
+ */
+ private function chapterQuery()
+ {
+ return $this->restrictionService->enforceChapterRestrictions($this->chapter, 'view');
}
/**
@@ -26,7 +39,7 @@ class ChapterRepo
*/
public function idExists($id)
{
- return $this->chapter->where('id', '=', $id)->count() > 0;
+ return $this->chapterQuery()->where('id', '=', $id)->count() > 0;
}
/**
@@ -36,7 +49,7 @@ class ChapterRepo
*/
public function getById($id)
{
- return $this->chapter->findOrFail($id);
+ return $this->chapterQuery()->findOrFail($id);
}
/**
@@ -45,7 +58,7 @@ class ChapterRepo
*/
public function getAll()
{
- return $this->chapter->all();
+ return $this->chapterQuery()->all();
}
/**
@@ -56,7 +69,7 @@ class ChapterRepo
*/
public function getBySlug($slug, $bookId)
{
- $chapter = $this->chapter->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
+ $chapter = $this->chapterQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
if ($chapter === null) abort(404);
return $chapter;
}
@@ -132,7 +145,7 @@ class ChapterRepo
public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $chapters = $this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms)
+ $chapters = $this->restrictionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
foreach ($chapters as $chapter) {
diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php
index 28942d94a..46e1d98a5 100644
--- a/app/Repos/EntityRepo.php
+++ b/app/Repos/EntityRepo.php
@@ -4,6 +4,7 @@
use BookStack\Book;
use BookStack\Chapter;
use BookStack\Page;
+use BookStack\Services\RestrictionService;
class EntityRepo
{
@@ -11,18 +12,21 @@ class EntityRepo
public $book;
public $chapter;
public $page;
+ private $restrictionService;
/**
* EntityService constructor.
- * @param $book
- * @param $chapter
- * @param $page
+ * @param Book $book
+ * @param Chapter $chapter
+ * @param Page $page
+ * @param RestrictionService $restrictionService
*/
- public function __construct(Book $book, Chapter $chapter, Page $page)
+ public function __construct(Book $book, Chapter $chapter, Page $page, RestrictionService $restrictionService)
{
$this->book = $book;
$this->chapter = $chapter;
$this->page = $page;
+ $this->restrictionService = $restrictionService;
}
/**
@@ -32,7 +36,8 @@ class EntityRepo
*/
public function getRecentlyCreatedBooks($count = 20, $page = 0)
{
- return $this->book->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ return $this->restrictionService->enforceBookRestrictions($this->book)
+ ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
}
/**
@@ -43,7 +48,8 @@ class EntityRepo
*/
public function getRecentlyUpdatedBooks($count = 20, $page = 0)
{
- return $this->book->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ return $this->restrictionService->enforceBookRestrictions($this->book)
+ ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
}
/**
@@ -53,7 +59,8 @@ class EntityRepo
*/
public function getRecentlyCreatedPages($count = 20, $page = 0)
{
- return $this->page->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ return $this->restrictionService->enforcePageRestrictions($this->page)
+ ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
}
/**
@@ -64,7 +71,8 @@ class EntityRepo
*/
public function getRecentlyUpdatedPages($count = 20, $page = 0)
{
- return $this->page->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ return $this->restrictionService->enforcePageRestrictions($this->page)
+ ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
}
diff --git a/app/Repos/PageRepo.php b/app/Repos/PageRepo.php
index 1a98255ab..c4cf00e7c 100644
--- a/app/Repos/PageRepo.php
+++ b/app/Repos/PageRepo.php
@@ -4,6 +4,7 @@
use Activity;
use BookStack\Book;
use BookStack\Chapter;
+use BookStack\Services\RestrictionService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@@ -16,26 +17,28 @@ class PageRepo
{
protected $page;
protected $pageRevision;
+ protected $restrictionService;
/**
* PageRepo constructor.
- * @param Page $page
+ * @param Page $page
* @param PageRevision $pageRevision
+ * @param RestrictionService $restrictionService
*/
- public function __construct(Page $page, PageRevision $pageRevision)
+ public function __construct(Page $page, PageRevision $pageRevision, RestrictionService $restrictionService)
{
$this->page = $page;
$this->pageRevision = $pageRevision;
+ $this->restrictionService = $restrictionService;
}
/**
- * Check if a page id exists.
- * @param $id
- * @return bool
+ * Base query for getting pages, Takes restrictions into account.
+ * @return mixed
*/
- public function idExists($id)
+ private function pageQuery()
{
- return $this->page->where('page_id', '=', $id)->count() > 0;
+ return $this->restrictionService->enforcePageRestrictions($this->page, 'view');
}
/**
@@ -45,16 +48,7 @@ class PageRepo
*/
public function getById($id)
{
- return $this->page->findOrFail($id);
- }
-
- /**
- * Get all pages.
- * @return \Illuminate\Database\Eloquent\Collection|static[]
- */
- public function getAll()
- {
- return $this->page->all();
+ return $this->pageQuery()->findOrFail($id);
}
/**
@@ -65,7 +59,7 @@ class PageRepo
*/
public function getBySlug($slug, $bookId)
{
- $page = $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
+ $page = $this->pageQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
if ($page === null) throw new NotFoundHttpException('Page not found');
return $page;
}
@@ -81,6 +75,9 @@ class PageRepo
public function findPageUsingOldSlug($pageSlug, $bookSlug)
{
$revision = $this->pageRevision->where('slug', '=', $pageSlug)
+ ->whereHas('page', function($query) {
+ $this->restrictionService->enforcePageRestrictions($query);
+ })
->where('book_slug', '=', $bookSlug)->orderBy('created_at', 'desc')
->with('page')->first();
return $revision !== null ? $revision->page : null;
@@ -97,16 +94,6 @@ class PageRepo
return $page;
}
- /**
- * Count the pages with a particular slug within a book.
- * @param $slug
- * @param $bookId
- * @return mixed
- */
- public function countBySlug($slug, $bookId)
- {
- return $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->count();
- }
/**
* Save a new page into the system.
@@ -202,7 +189,7 @@ class PageRepo
public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $pages = $this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms)
+ $pages = $this->restrictionService->enforcePageRestrictions($this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms))
->paginate($count)->appends($paginationAppends);
// Add highlights to page text.
@@ -240,7 +227,7 @@ class PageRepo
*/
public function searchForImage($imageString)
{
- $pages = $this->page->where('html', 'like', '%' . $imageString . '%')->get();
+ $pages = $this->pageQuery()->where('html', 'like', '%' . $imageString . '%')->get();
foreach ($pages as $page) {
$page->url = $page->getUrl();
$page->html = '';
@@ -395,7 +382,7 @@ class PageRepo
*/
public function getRecentlyCreatedPaginated($count = 20)
{
- return $this->page->orderBy('created_at', 'desc')->paginate($count);
+ return $this->pageQuery()->orderBy('created_at', 'desc')->paginate($count);
}
/**
@@ -404,7 +391,7 @@ class PageRepo
*/
public function getRecentlyUpdatedPaginated($count = 20)
{
- return $this->page->orderBy('updated_at', 'desc')->paginate($count);
+ return $this->pageQuery()->orderBy('updated_at', 'desc')->paginate($count);
}
/**
diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php
index a065ae01f..a57210b8d 100644
--- a/app/Services/ActivityService.php
+++ b/app/Services/ActivityService.php
@@ -9,14 +9,17 @@ class ActivityService
{
protected $activity;
protected $user;
+ protected $restrictionService;
/**
* ActivityService constructor.
- * @param $activity
+ * @param Activity $activity
+ * @param RestrictionService $restrictionService
*/
- public function __construct(Activity $activity)
+ public function __construct(Activity $activity, RestrictionService $restrictionService)
{
$this->activity = $activity;
+ $this->restrictionService = $restrictionService;
$this->user = auth()->user();
}
@@ -86,8 +89,10 @@ class ActivityService
*/
public function latest($count = 20, $page = 0)
{
- $activityList = $this->activity->orderBy('created_at', 'desc')
- ->skip($count * $page)->take($count)->get();
+ $activityList = $this->restrictionService
+ ->filterRestrictedEntityRelations($this->activity, 'activities', 'entity_id', 'entity_type')
+ ->orderBy('created_at', 'desc')->skip($count * $page)->take($count)->get();
+
return $this->filterSimilar($activityList);
}
diff --git a/app/Services/RestrictionService.php b/app/Services/RestrictionService.php
new file mode 100644
index 000000000..87dcbf0b3
--- /dev/null
+++ b/app/Services/RestrictionService.php
@@ -0,0 +1,230 @@
+userRoles = auth()->user()->roles->pluck('id');
+ $this->isAdmin = auth()->user()->hasRole('admin');
+ }
+
+ /**
+ * Add restrictions for a page query
+ * @param $query
+ * @param string $action
+ * @return mixed
+ */
+ public function enforcePageRestrictions($query, $action = 'view')
+ {
+ if ($this->isAdmin) return $query;
+ $this->currentAction = $action;
+ return $this->pageRestrictionQuery($query);
+ }
+
+ /**
+ * The base query for restricting pages.
+ * @param $query
+ * @return mixed
+ */
+ private function pageRestrictionQuery($query)
+ {
+ return $query->where(function ($parentWhereQuery) {
+
+ $parentWhereQuery
+ // (Book & chapter & page) or (Book & page & NO CHAPTER) unrestricted
+ ->where(function ($query) {
+ $query->where(function ($query) {
+ $query->whereExists(function ($query) {
+ $query->select('*')->from('chapters')
+ ->whereRaw('chapters.id=pages.chapter_id')
+ ->where('restricted', '=', false);
+ })->whereExists(function ($query) {
+ $query->select('*')->from('books')
+ ->whereRaw('books.id=pages.book_id')
+ ->where('restricted', '=', false);
+ })->where('restricted', '=', false);
+ })->orWhere(function ($query) {
+ $query->where('restricted', '=', false)->where('chapter_id', '=', 0)
+ ->whereExists(function ($query) {
+ $query->select('*')->from('books')
+ ->whereRaw('books.id=pages.book_id')
+ ->where('restricted', '=', false);
+ });
+ });
+ })
+ // Page unrestricted, Has no chapter & book has accepted restrictions
+ ->orWhere(function ($query) {
+ $query->where('restricted', '=', false)
+ ->whereExists(function ($query) {
+ $query->select('*')->from('chapters')
+ ->whereRaw('chapters.id=pages.chapter_id');
+ }, 'and', true)
+ ->whereExists(function ($query) {
+ $query->select('*')->from('books')
+ ->whereRaw('books.id=pages.book_id')
+ ->whereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'books', 'Book');
+ });
+ });
+ })
+ // Page unrestricted, Has a chapter with accepted permissions
+ ->orWhere(function ($query) {
+ $query->where('restricted', '=', false)
+ ->whereExists(function ($query) {
+ $query->select('*')->from('chapters')
+ ->whereRaw('chapters.id=pages.chapter_id')
+ ->whereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'chapters', 'Chapter');
+ });
+ });
+ })
+ // Page has accepted permissions
+ ->orWhereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'pages', 'Page');
+ });
+ });
+ }
+
+ /**
+ * Add on permission restrictions to a chapter query.
+ * @param $query
+ * @param string $action
+ * @return mixed
+ */
+ public function enforceChapterRestrictions($query, $action = 'view')
+ {
+ if ($this->isAdmin) return $query;
+ $this->currentAction = $action;
+ return $this->chapterRestrictionQuery($query);
+ }
+
+ /**
+ * The base query for restricting chapters.
+ * @param $query
+ * @return mixed
+ */
+ private function chapterRestrictionQuery($query)
+ {
+ return $query->where(function ($parentWhereQuery) {
+
+ $parentWhereQuery
+ // Book & chapter unrestricted
+ ->where(function ($query) {
+ $query->where('restricted', '=', false)->whereExists(function ($query) {
+ $query->select('*')->from('books')
+ ->whereRaw('books.id=chapters.book_id')
+ ->where('restricted', '=', false);
+ });
+ })
+ // Chapter unrestricted & book has accepted restrictions
+ ->orWhere(function ($query) {
+ $query->where('restricted', '=', false)
+ ->whereExists(function ($query) {
+ $query->select('*')->from('books')
+ ->whereRaw('books.id=chapters.book_id')
+ ->whereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'books', 'Book');
+ });
+ });
+ })
+ // Chapter has accepted permissions
+ ->orWhereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'chapters', 'Chapter');
+ });
+ });
+ }
+
+ /**
+ * Add restrictions to a book query.
+ * @param $query
+ * @param string $action
+ * @return mixed
+ */
+ public function enforceBookRestrictions($query, $action = 'view')
+ {
+ if ($this->isAdmin) return $query;
+ $this->currentAction = $action;
+ return $this->bookRestrictionQuery($query);
+ }
+
+ /**
+ * The base query for restricting books.
+ * @param $query
+ * @return mixed
+ */
+ private function bookRestrictionQuery($query)
+ {
+ return $query->where(function ($parentWhereQuery) {
+ $parentWhereQuery
+ ->where('restricted', '=', false)
+ ->orWhereExists(function ($query) {
+ $this->checkRestrictionsQuery($query, 'books', 'Book');
+ });
+ });
+ }
+
+ /**
+ * Filter items that have entities set a a polymorphic relation.
+ * @param $query
+ * @param string $tableName
+ * @param string $entityIdColumn
+ * @param string $entityTypeColumn
+ * @return mixed
+ */
+ public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn)
+ {
+ if ($this->isAdmin) return $query;
+ $this->currentAction = 'view';
+ $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
+ return $query->where(function($query) use ($tableDetails) {
+ $query->where(function ($query) use (&$tableDetails) {
+ $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Page')
+ ->whereExists(function ($query) use (&$tableDetails) {
+ $query->select('*')->from('pages')->whereRaw('pages.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn'])
+ ->where(function ($query) {
+ $this->pageRestrictionQuery($query);
+ });
+ });
+ })->orWhere(function ($query) use (&$tableDetails) {
+ $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Book')->whereExists(function ($query) use (&$tableDetails) {
+ $query->select('*')->from('books')->whereRaw('books.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn'])
+ ->where(function ($query) {
+ $this->bookRestrictionQuery($query);
+ });
+ });
+ })->orWhere(function ($query) use (&$tableDetails) {
+ $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Chapter')->whereExists(function ($query) use (&$tableDetails) {
+ $query->select('*')->from('chapters')->whereRaw('chapters.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn'])
+ ->where(function ($query) {
+ $this->chapterRestrictionQuery($query);
+ });
+ });
+ });
+ });
+ }
+
+ /**
+ * The query to check the restrictions on an entity.
+ * @param $query
+ * @param $tableName
+ * @param $modelName
+ */
+ private function checkRestrictionsQuery($query, $tableName, $modelName)
+ {
+ $query->select('*')->from('restrictions')
+ ->whereRaw('restrictions.restrictable_id=' . $tableName . '.id')
+ ->where('restrictions.restrictable_type', '=', 'BookStack\\' . $modelName)
+ ->where('restrictions.action', '=', $this->currentAction)
+ ->whereIn('restrictions.role_id', $this->userRoles);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/Services/ViewService.php b/app/Services/ViewService.php
index 5b800d939..75ffd21dc 100644
--- a/app/Services/ViewService.php
+++ b/app/Services/ViewService.php
@@ -9,15 +9,18 @@ class ViewService
protected $view;
protected $user;
+ protected $restrictionService;
/**
* ViewService constructor.
- * @param $view
+ * @param View $view
+ * @param RestrictionService $restrictionService
*/
- public function __construct(View $view)
+ public function __construct(View $view, RestrictionService $restrictionService)
{
$this->view = $view;
$this->user = auth()->user();
+ $this->restrictionService = $restrictionService;
}
/**
@@ -27,7 +30,7 @@ class ViewService
*/
public function add(Entity $entity)
{
- if($this->user === null) return 0;
+ if ($this->user === null) return 0;
$view = $entity->views()->where('user_id', '=', $this->user->id)->first();
// Add view if model exists
if ($view) {
@@ -47,18 +50,19 @@ class ViewService
/**
* Get the entities with the most views.
- * @param int $count
- * @param int $page
+ * @param int $count
+ * @param int $page
* @param bool|false $filterModel
*/
public function getPopular($count = 10, $page = 0, $filterModel = false)
{
$skipCount = $count * $page;
- $query = $this->view->select('id', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
+ $query = $this->restrictionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type')
+ ->select('id', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
->groupBy('viewable_id', 'viewable_type')
->orderBy('view_count', 'desc');
- if($filterModel) $query->where('viewable_type', '=', get_class($filterModel));
+ if ($filterModel) $query->where('viewable_type', '=', get_class($filterModel));
$views = $query->with('viewable')->skip($skipCount)->take($count)->get();
$viewedEntities = $views->map(function ($item) {
@@ -69,22 +73,24 @@ class ViewService
/**
* Get all recently viewed entities for the current user.
- * @param int $count
- * @param int $page
+ * @param int $count
+ * @param int $page
* @param Entity|bool $filterModel
* @return mixed
*/
public function getUserRecentlyViewed($count = 10, $page = 0, $filterModel = false)
{
- if($this->user === null) return collect();
+ if ($this->user === null) return collect();
$skipCount = $count * $page;
- $query = $this->view->where('user_id', '=', auth()->user()->id);
+ $query = $this->restrictionService
+ ->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
- if ($filterModel) $query->where('viewable_type', '=', get_class($filterModel));
+ if ($filterModel) $query = $query->where('viewable_type', '=', get_class($filterModel));
+ $query = $query->where('user_id', '=', auth()->user()->id);
$views = $query->with('viewable')->orderBy('updated_at', 'desc')->skip($skipCount)->take($count)->get();
$viewedEntities = $views->map(function ($item) {
- return $item->viewable()->getResults();
+ return $item->viewable;
});
return $viewedEntities;
}
diff --git a/resources/views/partials/activity-item.blade.php b/resources/views/partials/activity-item.blade.php
index f94fad5e1..00ca574dd 100644
--- a/resources/views/partials/activity-item.blade.php
+++ b/resources/views/partials/activity-item.blade.php
@@ -17,7 +17,7 @@
{{ $activity->getText() }}
@if($activity->entity())
- {{ $activity->entity()->name }}
+ {{ $activity->entity->name }}
@endif
@if($activity->extra) "{{$activity->extra}}" @endif