mirror of
https://github.com/flarum/core.git
synced 2025-08-09 18:07:02 +02:00
Model Visibility Scoping Extender and Tests (#2460)
This commit is contained in:
committed by
GitHub
parent
e0437d237a
commit
8901073d12
@@ -12,19 +12,49 @@ namespace Flarum\Database;
|
||||
use Flarum\Event\ScopeModelVisibility;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
trait ScopeVisibilityTrait
|
||||
{
|
||||
protected static $visibilityScopers = [];
|
||||
|
||||
public static function registerVisibilityScoper($scoper, $ability = null)
|
||||
{
|
||||
$model = static::class;
|
||||
|
||||
if ($ability === null) {
|
||||
$ability = '*';
|
||||
}
|
||||
|
||||
if (! Arr::has(static::$visibilityScopers, "$model.$ability")) {
|
||||
Arr::set(static::$visibilityScopers, "$model.$ability", []);
|
||||
}
|
||||
|
||||
static::$visibilityScopers[$model][$ability][] = $scoper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include records that are visible to a user.
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param User $actor
|
||||
*/
|
||||
public function scopeWhereVisibleTo(Builder $query, User $actor)
|
||||
public function scopeWhereVisibleTo(Builder $query, User $actor, string $ability = 'view')
|
||||
{
|
||||
static::$dispatcher->dispatch(
|
||||
new ScopeModelVisibility($query, $actor, 'view')
|
||||
);
|
||||
/**
|
||||
* @deprecated beta 15, remove beta 15
|
||||
*/
|
||||
static::$dispatcher->dispatch(new ScopeModelVisibility($query, $actor, $ability));
|
||||
|
||||
foreach (array_reverse(array_merge([static::class], class_parents($this))) as $class) {
|
||||
foreach (Arr::get(static::$visibilityScopers, "$class.*", []) as $listener) {
|
||||
$listener($actor, $query, $ability);
|
||||
}
|
||||
foreach (Arr::get(static::$visibilityScopers, "$class.$ability", []) as $listener) {
|
||||
$listener($actor, $query);
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
61
src/Discussion/Access/ScopeDiscussionVisibility.php
Normal file
61
src/Discussion/Access/ScopeDiscussionVisibility.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Access;
|
||||
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ScopeDiscussionVisibility
|
||||
{
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function __invoke(User $actor, $query)
|
||||
{
|
||||
if ($actor->cannot('viewDiscussions')) {
|
||||
$query->whereRaw('FALSE');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide private discussions by default.
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('discussions.is_private', false)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$query->whereVisibleTo($actor, 'viewPrivate');
|
||||
});
|
||||
});
|
||||
|
||||
// Hide hidden discussions, unless they are authored by the current
|
||||
// user, or the current user has permission to view hidden discussions.
|
||||
if (! $actor->hasPermission('discussion.hide')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->whereNull('discussions.hidden_at')
|
||||
->orWhere('discussions.user_id', $actor->id)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$query->whereVisibleTo($actor, 'hide');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Hide discussions with no comments, unless they are authored by the
|
||||
// current user, or the user is allowed to edit the discussion's posts.
|
||||
if (! $actor->hasPermission('discussion.editPosts')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('discussions.comment_count', '>', 0)
|
||||
->orWhere('discussions.user_id', $actor->id)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$query->whereVisibleTo($actor, 'editPosts');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,12 +9,10 @@
|
||||
|
||||
namespace Flarum\Discussion;
|
||||
|
||||
use Flarum\Event\ScopeModelVisibility;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\AbstractPolicy;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class DiscussionPolicy extends AbstractPolicy
|
||||
{
|
||||
@@ -55,57 +53,6 @@ class DiscussionPolicy extends AbstractPolicy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function find(User $actor, Builder $query)
|
||||
{
|
||||
if ($actor->cannot('viewDiscussions')) {
|
||||
$query->whereRaw('FALSE');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide private discussions by default.
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('discussions.is_private', false)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility($query, $actor, 'viewPrivate')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Hide hidden discussions, unless they are authored by the current
|
||||
// user, or the current user has permission to view hidden discussions.
|
||||
if (! $actor->hasPermission('discussion.hide')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->whereNull('discussions.hidden_at')
|
||||
->orWhere('discussions.user_id', $actor->id)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility($query, $actor, 'hide')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Hide discussions with no comments, unless they are authored by the
|
||||
// current user, or the user is allowed to edit the discussion's posts.
|
||||
if (! $actor->hasPermission('discussion.editPosts')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('discussions.comment_count', '>', 0)
|
||||
->orWhere('discussions.user_id', $actor->id)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility($query, $actor, 'editPosts')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param \Flarum\Discussion\Discussion $discussion
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Flarum\Discussion;
|
||||
|
||||
use Flarum\Discussion\Access\ScopeDiscussionVisibility;
|
||||
use Flarum\Discussion\Event\Renamed;
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
|
||||
@@ -28,5 +29,7 @@ class DiscussionServiceProvider extends AbstractServiceProvider
|
||||
Renamed::class,
|
||||
DiscussionRenamedLogger::class
|
||||
);
|
||||
|
||||
Discussion::registerVisibilityScoper(new ScopeDiscussionVisibility(), 'view');
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
/**
|
||||
* The `ScopeModelVisibility` event allows constraints to be applied in a query
|
||||
* to fetch a model, effectively scoping that model's visibility to the user.
|
||||
*
|
||||
* @deprecated beta 15, remove beta 16
|
||||
*/
|
||||
class ScopeModelVisibility
|
||||
{
|
||||
|
102
src/Extend/ModelVisibility.php
Normal file
102
src/Extend/ModelVisibility.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Extend;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Foundation\ContainerUtil;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
|
||||
/**
|
||||
* Model visibility scoping allows us to scope queries based on the current user.
|
||||
* The main usage of this is only showing model instances that a user is allowed to see.
|
||||
*
|
||||
* This is done by running a query through a series of "scoper" callbacks, which apply
|
||||
* additional `where`s to the query based on the user.
|
||||
*
|
||||
* Scopers are classified under an ability. Calling `whereVisibleTo` on a query
|
||||
* will apply scopers under the `view` ability. Generally, the main `view` scopers
|
||||
* can request scoping with other abilities, which provides an entrypoint for extensions
|
||||
* to modify some restriction to a query.
|
||||
*
|
||||
* Scopers registered via `scopeAll` will apply to all queries under a model, regardless
|
||||
* of the ability, and will accept the ability name as an additional argument.
|
||||
*/
|
||||
class ModelVisibility implements ExtenderInterface
|
||||
{
|
||||
private $modelClass;
|
||||
private $scopers = [];
|
||||
private $allScopers = [];
|
||||
|
||||
/**
|
||||
* @param string $modelClass The ::class attribute of the model you are applying scopers to.
|
||||
* This model must extend from \Flarum\Database\AbstractModel,
|
||||
* and use \Flarum\Database\ScopeVisibilityTrait.
|
||||
*/
|
||||
public function __construct(string $modelClass)
|
||||
{
|
||||
$this->modelClass = $modelClass;
|
||||
|
||||
if (! method_exists($modelClass, 'registerVisibilityScoper')) {
|
||||
throw new Exception("Model $modelClass cannot be visibility scoped as it does not use Flarum\Database\ScopeVisibilityTrait.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a scoper for a given ability.
|
||||
*
|
||||
* @param callable|string $callback
|
||||
* @param string $ability, defaults to 'view'
|
||||
*
|
||||
* The callback can be a closure or invokable class, and should accept:
|
||||
* - \Flarum\User\User $actor
|
||||
* - \Illuminate\Database\Eloquent\Builder $query
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function scope($callback, $ability = 'view')
|
||||
{
|
||||
$this->scopers[$ability][] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a scoper scoper that will always run for this model, regardless of requested ability.
|
||||
*
|
||||
* @param callable|string $callback
|
||||
*
|
||||
* The callback can be a closure or invokable class, and should accept:
|
||||
* - \Flarum\User\User $actor
|
||||
* - \Illuminate\Database\Eloquent\Builder $query
|
||||
* - string $ability
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function scopeAll($callback)
|
||||
{
|
||||
$this->allScopers[] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
foreach ($this->scopers as $ability => $scopers) {
|
||||
foreach ($scopers as $scoper) {
|
||||
$this->modelClass::registerVisibilityScoper(ContainerUtil::wrapCallback($scoper, $container), $ability);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->allScopers as $scoper) {
|
||||
$this->modelClass::registerVisibilityScoper(ContainerUtil::wrapCallback($scoper, $container));
|
||||
}
|
||||
}
|
||||
}
|
27
src/Group/Access/ScopeGroupVisibility.php
Normal file
27
src/Group/Access/ScopeGroupVisibility.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Access;
|
||||
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ScopeGroupVisibility
|
||||
{
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function __invoke(User $actor, $query)
|
||||
{
|
||||
if ($actor->cannot('viewHiddenGroups')) {
|
||||
$query->where('is_hidden', false);
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,7 +11,6 @@ namespace Flarum\Group;
|
||||
|
||||
use Flarum\User\AbstractPolicy;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class GroupPolicy extends AbstractPolicy
|
||||
{
|
||||
@@ -31,15 +30,4 @@ class GroupPolicy extends AbstractPolicy
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function find(User $actor, Builder $query)
|
||||
{
|
||||
if ($actor->cannot('viewHiddenGroups')) {
|
||||
$query->where('is_hidden', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
namespace Flarum\Group;
|
||||
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Group\Access\ScopeGroupVisibility;
|
||||
|
||||
class GroupServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
@@ -20,5 +21,7 @@ class GroupServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
$events = $this->app->make('events');
|
||||
$events->subscribe(GroupPolicy::class);
|
||||
|
||||
Group::registerVisibilityScoper(new ScopeGroupVisibility(), 'view');
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ namespace Flarum\Notification;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Database\AbstractModel;
|
||||
use Flarum\Event\ScopeModelVisibility;
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
@@ -161,9 +160,9 @@ class Notification extends AbstractModel
|
||||
->from((new $class)->getTable())
|
||||
->whereColumn('id', 'subject_id');
|
||||
|
||||
static::$dispatcher->dispatch(
|
||||
new ScopeModelVisibility($class::query()->setQuery($query), $actor, 'view')
|
||||
);
|
||||
if (method_exists($class, 'registerVisibilityScoper')) {
|
||||
$class::query()->setQuery($query)->whereVisibleTo($actor);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
62
src/Post/Access/ScopePostVisibility.php
Normal file
62
src/Post/Access/ScopePostVisibility.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Access;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ScopePostVisibility
|
||||
{
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function __invoke(User $actor, $query)
|
||||
{
|
||||
// Make sure the post's discussion is visible as well.
|
||||
$query->whereExists(function ($query) use ($actor) {
|
||||
$query->selectRaw('1')
|
||||
->from('discussions')
|
||||
->whereColumn('discussions.id', 'posts.discussion_id');
|
||||
Discussion::query()->setQuery($query)->whereVisibleTo($actor);
|
||||
});
|
||||
|
||||
// Hide private posts by default.
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('posts.is_private', false)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$query->whereVisibleTo($actor, 'viewPrivate');
|
||||
});
|
||||
});
|
||||
|
||||
// Hide hidden posts, unless they are authored by the current user, or
|
||||
// the current user has permission to view hidden posts in the
|
||||
// discussion.
|
||||
if (! $actor->hasPermission('discussion.hidePosts')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->whereNull('posts.hidden_at')
|
||||
->orWhere('posts.user_id', $actor->id)
|
||||
->orWhereExists(function ($query) use ($actor) {
|
||||
$query->selectRaw('1')
|
||||
->from('discussions')
|
||||
->whereColumn('discussions.id', 'posts.discussion_id')
|
||||
->where(function ($query) use ($actor) {
|
||||
$query
|
||||
->whereRaw('1=0')
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
Discussion::query()->setQuery($query)->whereVisibleTo($actor, 'hidePosts');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,13 +10,10 @@
|
||||
namespace Flarum\Post;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Event\ScopeModelVisibility;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\AbstractPolicy;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class PostPolicy extends AbstractPolicy
|
||||
{
|
||||
@@ -58,58 +55,6 @@ class PostPolicy extends AbstractPolicy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function find(User $actor, $query)
|
||||
{
|
||||
// Make sure the post's discussion is visible as well.
|
||||
$query->whereExists(function ($query) use ($actor) {
|
||||
$query->selectRaw('1')
|
||||
->from('discussions')
|
||||
->whereColumn('discussions.id', 'posts.discussion_id');
|
||||
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility(Discussion::query()->setQuery($query), $actor, 'view')
|
||||
);
|
||||
});
|
||||
|
||||
// Hide private posts by default.
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->where('posts.is_private', false)
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility($query, $actor, 'viewPrivate')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Hide hidden posts, unless they are authored by the current user, or
|
||||
// the current user has permission to view hidden posts in the
|
||||
// discussion.
|
||||
if (! $actor->hasPermission('discussion.hidePosts')) {
|
||||
$query->where(function ($query) use ($actor) {
|
||||
$query->whereNull('posts.hidden_at')
|
||||
->orWhere('posts.user_id', $actor->id)
|
||||
->orWhereExists(function ($query) use ($actor) {
|
||||
$query->selectRaw('1')
|
||||
->from('discussions')
|
||||
->whereColumn('discussions.id', 'posts.discussion_id')
|
||||
->where(function ($query) use ($actor) {
|
||||
$query
|
||||
->whereRaw('1=0')
|
||||
->orWhere(function ($query) use ($actor) {
|
||||
$this->events->dispatch(
|
||||
new ScopeModelVisibility(Discussion::query()->setQuery($query), $actor, 'hidePosts')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Post $post
|
||||
|
@@ -12,6 +12,7 @@ namespace Flarum\Post;
|
||||
use DateTime;
|
||||
use Flarum\Event\ConfigurePostTypes;
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Post\Access\ScopePostVisibility;
|
||||
|
||||
class PostServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
@@ -52,6 +53,8 @@ class PostServiceProvider extends AbstractServiceProvider
|
||||
|
||||
$events = $this->app->make('events');
|
||||
$events->subscribe(PostPolicy::class);
|
||||
|
||||
Post::registerVisibilityScoper(new ScopePostVisibility(), 'view');
|
||||
}
|
||||
|
||||
protected function setPostTypes()
|
||||
|
@@ -54,6 +54,7 @@ abstract class AbstractPolicy
|
||||
|
||||
/**
|
||||
* @param ScopeModelVisibility $event
|
||||
* @deprecated beta 15, remove beta 16
|
||||
*/
|
||||
public function scopeModelVisibility(ScopeModelVisibility $event)
|
||||
{
|
||||
|
31
src/User/Access/ScopeUserVisibility.php
Normal file
31
src/User/Access/ScopeUserVisibility.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Access;
|
||||
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ScopeUserVisibility
|
||||
{
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function __invoke(User $actor, $query)
|
||||
{
|
||||
if ($actor->cannot('viewDiscussions')) {
|
||||
if ($actor->isGuest()) {
|
||||
$query->whereRaw('FALSE');
|
||||
} else {
|
||||
$query->where('id', $actor->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,8 +9,6 @@
|
||||
|
||||
namespace Flarum\User;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class UserPolicy extends AbstractPolicy
|
||||
{
|
||||
/**
|
||||
@@ -29,19 +27,4 @@ class UserPolicy extends AbstractPolicy
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Builder $query
|
||||
*/
|
||||
public function find(User $actor, Builder $query)
|
||||
{
|
||||
if ($actor->cannot('viewDiscussions')) {
|
||||
if ($actor->isGuest()) {
|
||||
$query->whereRaw('FALSE');
|
||||
} else {
|
||||
$query->where('id', $actor->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ namespace Flarum\User;
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Foundation\ContainerUtil;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\Access\ScopeUserVisibility;
|
||||
use Flarum\User\DisplayName\DriverInterface;
|
||||
use Flarum\User\DisplayName\UsernameDriver;
|
||||
use Flarum\User\Event\EmailChangeRequested;
|
||||
@@ -96,5 +97,7 @@ class UserServiceProvider extends AbstractServiceProvider
|
||||
User::registerPreference('discloseOnline', 'boolval', true);
|
||||
User::registerPreference('indexProfile', 'boolval', true);
|
||||
User::registerPreference('locale');
|
||||
|
||||
User::registerVisibilityScoper(new ScopeUserVisibility(), 'view');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user