diff --git a/extensions/likes/extend.php b/extensions/likes/extend.php index 58a03544d..0e78ef2cf 100644 --- a/extensions/likes/extend.php +++ b/extensions/likes/extend.php @@ -7,13 +7,14 @@ * LICENSE file that was distributed with this source code. */ +namespace Flarum\Likes; + use Flarum\Api\Controller; use Flarum\Api\Serializer\BasicUserSerializer; use Flarum\Api\Serializer\PostSerializer; use Flarum\Extend; use Flarum\Likes\Event\PostWasLiked; use Flarum\Likes\Event\PostWasUnliked; -use Flarum\Likes\Listener; use Flarum\Likes\Notification\PostLikedBlueprint; use Flarum\Likes\Query\LikedByFilter; use Flarum\Post\Event\Deleted; @@ -64,4 +65,10 @@ return [ (new Extend\Filter(PostFilterer::class)) ->addFilter(LikedByFilter::class), + + (new Extend\Settings()) + ->default('flarum-likes.like_own_post', true), + + (new Extend\Policy()) + ->modelPolicy(Post::class, Access\LikePostPolicy::class), ]; diff --git a/extensions/likes/js/src/admin/index.js b/extensions/likes/js/src/admin/index.js index 1acf3a396..6117298cb 100644 --- a/extensions/likes/js/src/admin/index.js +++ b/extensions/likes/js/src/admin/index.js @@ -1,12 +1,20 @@ import app from 'flarum/admin/app'; app.initializers.add('flarum-likes', () => { - app.extensionData.for('flarum-likes').registerPermission( - { - icon: 'far fa-thumbs-up', - label: app.translator.trans('flarum-likes.admin.permissions.like_posts_label'), - permission: 'discussion.likePosts', - }, - 'reply' - ); + app.extensionData + .for('flarum-likes') + .registerPermission( + { + icon: 'far fa-thumbs-up', + label: app.translator.trans('flarum-likes.admin.permissions.like_posts_label'), + permission: 'discussion.likePosts', + }, + 'reply' + ) + .registerSetting({ + setting: 'flarum-likes.like_own_post', + type: 'bool', + label: app.translator.trans('flarum-likes.admin.settings.like_own_posts_label'), + help: app.translator.trans('flarum-likes.admin.settings.like_own_posts_help'), + }); }); diff --git a/extensions/likes/locale/en.yml b/extensions/likes/locale/en.yml index 1d7a39e0b..19cac602e 100644 --- a/extensions/likes/locale/en.yml +++ b/extensions/likes/locale/en.yml @@ -11,6 +11,10 @@ flarum-likes: permissions: like_posts_label: Like posts + settings: + like_own_posts_help: When enabled, subject to permission, users may 'like' their own posts on the forum. To prevent users placing a 'like' on their own posts, disable this setting. + like_own_posts_label: Users may like their own posts + # Translations in this namespace are used by the forum user interface. forum: diff --git a/extensions/likes/src/Access/LikePostPolicy.php b/extensions/likes/src/Access/LikePostPolicy.php new file mode 100644 index 000000000..366ddc574 --- /dev/null +++ b/extensions/likes/src/Access/LikePostPolicy.php @@ -0,0 +1,35 @@ +settings = $settings; + } + + public function like(User $actor, Post $post) + { + if ($actor->id === $post->user_id && ! (bool) $this->settings->get('flarum-likes.like_own_post')) { + return $this->deny(); + } + } +} diff --git a/extensions/likes/tests/integration/api/LikePostTest.php b/extensions/likes/tests/integration/api/LikePostTest.php index 61e113e58..4bcbe49fa 100644 --- a/extensions/likes/tests/integration/api/LikePostTest.php +++ b/extensions/likes/tests/integration/api/LikePostTest.php @@ -48,7 +48,10 @@ class LikePostTest extends TestCase ['user_id' => 3, 'group_id' => 5] ] ]); + } + protected function rewriteDefaultPermissionsAfterBoot() + { $this->database()->table('group_permission')->where('permission', 'discussion.likePosts')->delete(); $this->database()->table('group_permission')->insert(['permission' => 'discussion.likePosts', 'group_id' => 5]); } @@ -57,8 +60,14 @@ class LikePostTest extends TestCase * @dataProvider allowedUsersToLike * @test */ - public function can_like_a_post_if_allowed(int $postId, ?int $authenticatedAs, string $message) + public function can_like_a_post_if_allowed(int $postId, ?int $authenticatedAs, string $message, bool $canLikeOwnPost = null) { + if (! is_null($canLikeOwnPost)) { + $this->setting('flarum-likes.like_own_post', $canLikeOwnPost); + } + + $this->rewriteDefaultPermissionsAfterBoot(); + $response = $this->sendLikeRequest($postId, $authenticatedAs); $post = CommentPost::query()->find($postId); @@ -71,8 +80,14 @@ class LikePostTest extends TestCase * @dataProvider unallowedUsersToLike * @test */ - public function cannot_like_a_post_if_not_allowed(int $postId, ?int $authenticatedAs, string $message) + public function cannot_like_a_post_if_not_allowed(int $postId, ?int $authenticatedAs, string $message, bool $canLikeOwnPost = null) { + if (! is_null($canLikeOwnPost)) { + $this->setting('flarum-likes.like_own_post', $canLikeOwnPost); + } + + $this->rewriteDefaultPermissionsAfterBoot(); + $response = $this->sendLikeRequest($postId, $authenticatedAs); $post = CommentPost::query()->find($postId); @@ -85,8 +100,14 @@ class LikePostTest extends TestCase * @dataProvider allowedUsersToLike * @test */ - public function can_dislike_a_post_if_liked_and_allowed(int $postId, ?int $authenticatedAs, string $message) + public function can_dislike_a_post_if_liked_and_allowed(int $postId, ?int $authenticatedAs, string $message, bool $canLikeOwnPost = null) { + if (! is_null($canLikeOwnPost)) { + $this->setting('flarum-likes.like_own_post', $canLikeOwnPost); + } + + $this->rewriteDefaultPermissionsAfterBoot(); + $this->sendLikeRequest($postId, $authenticatedAs); $response = $this->sendLikeRequest($postId, $authenticatedAs, false); @@ -101,7 +122,7 @@ class LikePostTest extends TestCase return [ [1, 1, 'Admin can like any post'], [1, 3, 'User with permission can like other posts'], - [6, 3, 'User with permission can like own post'] + [5, 3, 'User with permission can like own post by default'], ]; } @@ -109,7 +130,9 @@ class LikePostTest extends TestCase { return [ [1, null, 'Guest cannot like any post'], - [1, 2, 'User without permission cannot like any post'] + [1, 2, 'User without permission cannot like any post'], + [5, 3, 'User with permission cannot like own post if setting off', false], + [6, 1, 'Admin cannot like own post if setting off', false], ]; }