mirror of
https://github.com/flarum/framework.git
synced 2025-03-15 08:15:13 +08:00
fix(subscriptions): post notifications not getting access checked
Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
parent
02556c6ca6
commit
e5f05166a0
@ -21,6 +21,7 @@ use Flarum\Post\Event\Posted;
|
|||||||
use Flarum\Post\Event\Restored;
|
use Flarum\Post\Event\Restored;
|
||||||
use Flarum\Subscriptions\HideIgnoredFromAllDiscussionsPage;
|
use Flarum\Subscriptions\HideIgnoredFromAllDiscussionsPage;
|
||||||
use Flarum\Subscriptions\Listener;
|
use Flarum\Subscriptions\Listener;
|
||||||
|
use Flarum\Subscriptions\Notification\FilterVisiblePostsBeforeSending;
|
||||||
use Flarum\Subscriptions\Notification\NewPostBlueprint;
|
use Flarum\Subscriptions\Notification\NewPostBlueprint;
|
||||||
use Flarum\Subscriptions\Query\SubscriptionFilterGambit;
|
use Flarum\Subscriptions\Query\SubscriptionFilterGambit;
|
||||||
|
|
||||||
@ -36,7 +37,8 @@ return [
|
|||||||
->namespace('flarum-subscriptions', __DIR__.'/views'),
|
->namespace('flarum-subscriptions', __DIR__.'/views'),
|
||||||
|
|
||||||
(new Extend\Notification())
|
(new Extend\Notification())
|
||||||
->type(NewPostBlueprint::class, BasicDiscussionSerializer::class, ['alert', 'email']),
|
->type(NewPostBlueprint::class, BasicDiscussionSerializer::class, ['alert', 'email'])
|
||||||
|
->beforeSending(FilterVisiblePostsBeforeSending::class),
|
||||||
|
|
||||||
(new Extend\ApiSerializer(DiscussionSerializer::class))
|
(new Extend\ApiSerializer(DiscussionSerializer::class))
|
||||||
->attribute('subscription', function (DiscussionSerializer $serializer, Discussion $discussion) {
|
->attribute('subscription', function (DiscussionSerializer $serializer, Discussion $discussion) {
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Subscriptions\Notification;
|
||||||
|
|
||||||
|
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||||
|
|
||||||
|
class FilterVisiblePostsBeforeSending
|
||||||
|
{
|
||||||
|
public function __invoke(BlueprintInterface $blueprint, array $recipients): array
|
||||||
|
{
|
||||||
|
if ($blueprint instanceof NewPostBlueprint) {
|
||||||
|
$newRecipients = [];
|
||||||
|
|
||||||
|
// Flarum has built-in access control for the notification subject,
|
||||||
|
// but subscriptions post notifications has the discussion as the subject.
|
||||||
|
// We'll add a post visibility check so that users can't get access to hidden replies by subscribing.
|
||||||
|
foreach ($recipients as $recipient) {
|
||||||
|
if ($blueprint->post->isVisibleTo($recipient)) {
|
||||||
|
$newRecipients[] = $recipient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newRecipients;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $recipients;
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,9 @@
|
|||||||
namespace Flarum\Subscriptions\tests\integration\api\discussions;
|
namespace Flarum\Subscriptions\tests\integration\api\discussions;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Flarum\Extend\ModelVisibility;
|
||||||
use Flarum\Group\Group;
|
use Flarum\Group\Group;
|
||||||
|
use Flarum\Post\Post;
|
||||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||||
use Flarum\Testing\integration\TestCase;
|
use Flarum\Testing\integration\TestCase;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
@ -278,4 +280,47 @@ class ReplyNotificationTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals(1, $mainUser->getUnreadNotificationCount());
|
$this->assertEquals(1, $mainUser->getUnreadNotificationCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replying_to_a_discussion_with_a_restricted_post_only_sends_notifications_to_allowed_users()
|
||||||
|
{
|
||||||
|
// Add visibility scoper to only allow admin
|
||||||
|
// to see expected new post with content containing 'restricted-test-post'.
|
||||||
|
$this->extend(
|
||||||
|
(new ModelVisibility(Post::class))
|
||||||
|
->scope(function (User $actor, $query) {
|
||||||
|
if (! $actor->isAdmin()) {
|
||||||
|
$query->where('content', 'not like', '%restricted-test-post%');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->app();
|
||||||
|
|
||||||
|
/** @var User $allowedUser */
|
||||||
|
$allowedUser = User::query()->find(1);
|
||||||
|
$normalUser = User::query()->find(2);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $allowedUser->getUnreadNotificationCount());
|
||||||
|
$this->assertEquals(0, $normalUser->getUnreadNotificationCount());
|
||||||
|
|
||||||
|
$this->send(
|
||||||
|
$this->request('POST', '/api/posts', [
|
||||||
|
'authenticatedAs' => 3,
|
||||||
|
'json' => [
|
||||||
|
'data' => [
|
||||||
|
'attributes' => [
|
||||||
|
'content' => 'restricted-test-post',
|
||||||
|
],
|
||||||
|
'relationships' => [
|
||||||
|
'discussion' => ['data' => ['id' => 1]],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $allowedUser->getUnreadNotificationCount());
|
||||||
|
$this->assertEquals(0, $normalUser->getUnreadNotificationCount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user