1
0
mirror of https://github.com/flarum/core.git synced 2025-07-31 21:50:50 +02:00

Apply visibility permissions to mentionedBy relationship. fixes flarum/core#853

This commit is contained in:
Toby Zerner
2016-09-03 21:50:09 +09:30
parent c3cb99549c
commit f267a63ffe

View File

@@ -17,14 +17,29 @@ use Flarum\Api\Controller\ShowDiscussionController;
use Flarum\Api\Controller\ShowPostController;
use Flarum\Api\Serializer\PostBasicSerializer;
use Flarum\Core\Post;
use Flarum\Core\Repository\PostRepository;
use Flarum\Core\User;
use Flarum\Event\ConfigureApiController;
use Flarum\Event\GetApiRelationship;
use Flarum\Event\GetModelRelationship;
use Flarum\Event\PrepareApiData;
use Illuminate\Contracts\Events\Dispatcher;
class AddPostMentionedByRelationship
{
/**
* @var PostRepository
*/
protected $posts;
/**
* @param PostRepository $posts
*/
public function __construct(PostRepository $posts)
{
$this->posts = $posts;
}
/**
* @param Dispatcher $events
*/
@@ -33,6 +48,7 @@ class AddPostMentionedByRelationship
$events->listen(GetModelRelationship::class, [$this, 'getModelRelationship']);
$events->listen(GetApiRelationship::class, [$this, 'getApiRelationship']);
$events->listen(ConfigureApiController::class, [$this, 'includeRelationships']);
$events->listen(PrepareApiData::class, [$this, 'filterVisiblePosts']);
}
/**
@@ -102,4 +118,50 @@ class AddPostMentionedByRelationship
]);
}
}
/**
* Apply visibility permissions to API data.
*
* Each post in an API document has a relationship with posts that have
* mentioned it (mentionedBy). This listener will manually filter these
* additional posts so that the user can't see any posts which they don't
* have access to.
*
* @param PrepareApiData $event
*/
public function filterVisiblePosts(PrepareApiData $event)
{
// Firstly we gather a list of posts contained within the API document.
// This will vary according to the API endpoint that is being accessed.
if ($event->isController(ShowDiscussionController::class)) {
$posts = $event->data->posts;
} elseif ($event->isController(ShowPostController::class)) {
$posts = [$event->data];
} elseif ($event->isController(ListPostsController::class)) {
$posts = $event->data;
}
if (isset($posts)) {
$ids = [];
// Once we have the posts, construct a list of the IDs of all of
// the posts that they have been mentioned in. We can then filter
// this list of IDs to weed out all of the ones which the user is
// not meant to see.
foreach ($posts as $post) {
$ids = array_merge($ids, $post->mentionedBy->pluck('id')->all());
}
$ids = $this->posts->filterVisibleIds($ids, $event->actor);
// Finally, go back through each of the posts and filter out any
// of the posts in the relationship data that we now know are
// invisible to the user.
foreach ($posts as $post) {
$post->setRelation('mentionedBy', $post->mentionedBy->filter(function ($post) use ($ids) {
return array_search($post->id, $ids) !== false;
}));
}
}
}
}