From 96087d3f3d71a05e461ab071dd374c6a2adf2c08 Mon Sep 17 00:00:00 2001 From: Tristian Kelly Date: Thu, 6 Apr 2023 19:32:07 -0500 Subject: [PATCH 1/6] Add delete own posts permission --- .../src/admin/components/PermissionGrid.tsx | 25 +++++++ framework/core/locale/core.yml | 1 + .../core/src/Install/Steps/WriteSettings.php | 1 + framework/core/src/Post/Access/PostPolicy.php | 10 ++- .../integration/policy/PostPolicyTest.php | 75 +++++++++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) diff --git a/framework/core/js/src/admin/components/PermissionGrid.tsx b/framework/core/js/src/admin/components/PermissionGrid.tsx index 407552cd23..0ddcebda6f 100644 --- a/framework/core/js/src/admin/components/PermissionGrid.tsx +++ b/framework/core/js/src/admin/components/PermissionGrid.tsx @@ -366,6 +366,30 @@ export default class PermissionGrid { + const minutes = parseInt(app.data.settings.allow_hide_own_posts, 10); + + return SettingDropdown.component({ + defaultLabel: minutes + ? app.translator.trans('core.admin.permissions_controls.allow_some_minutes_button', { count: minutes }) + : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'), + key: 'allow_hide_own_posts', + options: [ + { value: '-1', label: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button') }, + { value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button') }, + { value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button') }, + ], + }); + }, + }, + 60 + ); + items.add( 'deletePosts', { @@ -375,6 +399,7 @@ export default class PermissionGrid 'reply', 'allow_post_editing' => 'reply', 'allow_renaming' => '10', 'allow_sign_up' => '1', diff --git a/framework/core/src/Post/Access/PostPolicy.php b/framework/core/src/Post/Access/PostPolicy.php index 9c5b5e812e..88fb041dee 100644 --- a/framework/core/src/Post/Access/PostPolicy.php +++ b/framework/core/src/Post/Access/PostPolicy.php @@ -71,6 +71,14 @@ public function edit(User $actor, Post $post) */ public function hide(User $actor, Post $post) { - return $this->edit($actor, $post); + if ($post->user_id == $actor->id && (! $post->hidden_at || $post->hidden_user_id == $actor->id) && $actor->can('reply', $post->discussion)) { + $allowHiding = $this->settings->get('allow_hide_own_posts'); + + if ($allowHiding === '-1' + || ($allowHiding === 'reply' && $post->number >= $post->discussion->last_post_number) + || (is_numeric($allowHiding) && $post->created_at->diffInMinutes(new Carbon) < $allowHiding)) { + return $this->allow(); + } + } } } diff --git a/framework/core/tests/integration/policy/PostPolicyTest.php b/framework/core/tests/integration/policy/PostPolicyTest.php index a9d5f5417d..d031c2305c 100644 --- a/framework/core/tests/integration/policy/PostPolicyTest.php +++ b/framework/core/tests/integration/policy/PostPolicyTest.php @@ -121,4 +121,79 @@ public function edit_10_minutes() $this->assertFalse($user->can('edit', $earlierPost)); $this->assertFalse($user->can('edit', $lastPost)); } + + /** + * @test + */ + public function hide_indefinitely() + { + $this->setting('allow_hide_own_posts', '-1'); + $this->app(); + + $user = User::findOrFail(2); + $earlierPost = Post::findOrFail(1); + $lastPost = Post::findOrFail(2); + + // Date close to "now" + Carbon::setTestNow('2021-11-01 13:00:05'); + + $this->assertTrue($user->can('hide', $earlierPost)); + $this->assertTrue($user->can('hide', $lastPost)); + + // Date further into the future + Carbon::setTestNow('2025-01-01 13:00:00'); + + $this->assertTrue($user->can('hide', $earlierPost)); + $this->assertTrue($user->can('hide', $lastPost)); + } + + /** + * @test + */ + public function hide_until_reply() + { + $this->setting('allow_hide_own_posts', 'reply'); + $this->app(); + + $user = User::findOrFail(2); + $earlierPost = Post::findOrFail(1); + $lastPost = Post::findOrFail(2); + + // Date close to "now" + Carbon::setTestNow('2021-11-01 13:00:05'); + + $this->assertFalse($user->can('hide', $earlierPost)); + $this->assertTrue($user->can('hide', $lastPost)); + + // Date further into the future + Carbon::setTestNow('2025-01-01 13:00:00'); + + $this->assertFalse($user->can('hide', $earlierPost)); + $this->assertTrue($user->can('hide', $lastPost)); + } + + /** + * @test + */ + public function hide_10_minutes() + { + $this->setting('allow_hide_own_posts', '10'); + $this->app(); + + $user = User::findOrFail(2); + $earlierPost = Post::findOrFail(1); + $lastPost = Post::findOrFail(2); + + // Date close to "now" + Carbon::setTestNow('2021-11-01 13:00:05'); + + $this->assertTrue($user->can('hide', $earlierPost)); + $this->assertTrue($user->can('hide', $lastPost)); + + // Date further into the future + Carbon::setTestNow('2025-01-01 13:00:00'); + + $this->assertFalse($user->can('hide', $earlierPost)); + $this->assertFalse($user->can('hide', $lastPost)); + } } From 72aa975c8143ca47022e3152c562d0bb98d73f10 Mon Sep 17 00:00:00 2001 From: Tristian Kelly Date: Thu, 6 Apr 2023 19:40:49 -0500 Subject: [PATCH 2/6] =?UTF-8?q?Forgot=20to=20order=20locale=20alphabetical?= =?UTF-8?q?ly=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/core/locale/core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/core/locale/core.yml b/framework/core/locale/core.yml index 8dffd99140..d468b904bf 100644 --- a/framework/core/locale/core.yml +++ b/framework/core/locale/core.yml @@ -194,13 +194,13 @@ core: # These translations are used in the Permissions page of the admin interface. permissions: + allow_delete_own_posts_label: Allow deleting own posts allow_post_editing_label: Allow post editing allow_renaming_label: Allow renaming create_access_token_label: Create access token create_heading: Create delete_discussions_forever_label: Delete discussions forever delete_discussions_label: Delete discussions - allow_delete_own_posts_label: Allow deleting own posts delete_posts_forever_label: Delete posts forever delete_posts_label: Delete posts description: Configure who can see and do what. From c57864ca2fb71c59313503d16514d1af7433010e Mon Sep 17 00:00:00 2001 From: Tristian Kelly Date: Thu, 6 Apr 2023 19:43:52 -0500 Subject: [PATCH 3/6] format --- framework/core/js/src/admin/components/PermissionGrid.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/core/js/src/admin/components/PermissionGrid.tsx b/framework/core/js/src/admin/components/PermissionGrid.tsx index 0ddcebda6f..6a43997aba 100644 --- a/framework/core/js/src/admin/components/PermissionGrid.tsx +++ b/framework/core/js/src/admin/components/PermissionGrid.tsx @@ -399,7 +399,6 @@ export default class PermissionGrid Date: Fri, 7 Apr 2023 13:55:16 -0500 Subject: [PATCH 4/6] Add never option --- .../src/admin/components/PermissionGrid.tsx | 1 + framework/core/locale/core.yml | 4 ++- .../integration/policy/PostPolicyTest.php | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/framework/core/js/src/admin/components/PermissionGrid.tsx b/framework/core/js/src/admin/components/PermissionGrid.tsx index 6a43997aba..7fa4228cfc 100644 --- a/framework/core/js/src/admin/components/PermissionGrid.tsx +++ b/framework/core/js/src/admin/components/PermissionGrid.tsx @@ -383,6 +383,7 @@ export default class PermissionGrid core.ref.never allow_some_minutes_button: "{count, plural, one {For # minute} other {For # minutes}}" allow_ten_minutes_button: For 10 minutes allow_until_reply_button: Until next reply @@ -490,7 +491,7 @@ core: log_out_button: => core.ref.log_out hide_access_token: Hide Token last_activity: Last activity - never: Never + never: => core.ref.never new_access_token_button: => core.ref.new_token new_access_token_modal: submit_button: Create Token @@ -802,6 +803,7 @@ core: log_in: Log In log_out: Log Out mark_all_as_read: Mark All as Read + never: Never new_token: New Token next_page: Next Page notifications: Notifications diff --git a/framework/core/tests/integration/policy/PostPolicyTest.php b/framework/core/tests/integration/policy/PostPolicyTest.php index d031c2305c..046cbf39e8 100644 --- a/framework/core/tests/integration/policy/PostPolicyTest.php +++ b/framework/core/tests/integration/policy/PostPolicyTest.php @@ -196,4 +196,29 @@ public function hide_10_minutes() $this->assertFalse($user->can('hide', $earlierPost)); $this->assertFalse($user->can('hide', $lastPost)); } + + /** + * @test + */ + public function hide_never() + { + $this->setting('allow_hide_own_posts', '0'); + $this->app(); + + $user = User::findOrFail(2); + $earlierPost = Post::findOrFail(1); + $lastPost = Post::findOrFail(2); + + // Date close to "now" + Carbon::setTestNow('2021-11-01 13:00:05'); + + $this->assertFalse($user->can('hide', $earlierPost)); + $this->assertFalse($user->can('hide', $lastPost)); + + // Date further into the future + Carbon::setTestNow('2025-01-01 13:00:00'); + + $this->assertFalse($user->can('hide', $earlierPost)); + $this->assertFalse($user->can('hide', $lastPost)); + } } From 19239b2a34d0c0e448fa391295a1a8e9235c6664 Mon Sep 17 00:00:00 2001 From: Tristian Kelly Date: Fri, 7 Apr 2023 14:02:38 -0500 Subject: [PATCH 5/6] why do i always forget to format --- framework/core/js/src/admin/components/PermissionGrid.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/core/js/src/admin/components/PermissionGrid.tsx b/framework/core/js/src/admin/components/PermissionGrid.tsx index 7fa4228cfc..215b4e7f8a 100644 --- a/framework/core/js/src/admin/components/PermissionGrid.tsx +++ b/framework/core/js/src/admin/components/PermissionGrid.tsx @@ -383,7 +383,7 @@ export default class PermissionGrid Date: Mon, 10 Apr 2023 14:47:52 -0500 Subject: [PATCH 6/6] Change delete to hide, rearrange permission grid --- .../src/admin/components/PermissionGrid.tsx | 50 +++++++++---------- framework/core/locale/core.yml | 2 +- .../core/src/Install/Steps/WriteSettings.php | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/framework/core/js/src/admin/components/PermissionGrid.tsx b/framework/core/js/src/admin/components/PermissionGrid.tsx index 215b4e7f8a..da88b3d4f4 100644 --- a/framework/core/js/src/admin/components/PermissionGrid.tsx +++ b/framework/core/js/src/admin/components/PermissionGrid.tsx @@ -288,6 +288,31 @@ export default class PermissionGrid { + const minutes = parseInt(app.data.settings.allow_hide_own_posts, 10); + + return SettingDropdown.component({ + defaultLabel: minutes + ? app.translator.trans('core.admin.permissions_controls.allow_some_minutes_button', { count: minutes }) + : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'), + key: 'allow_hide_own_posts', + options: [ + { value: '-1', label: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button') }, + { value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button') }, + { value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button') }, + { value: '0', label: app.translator.trans('core.admin.permissions_controls.allow_never_button') }, + ], + }); + }, + }, + 80 + ); + items.merge(app.extensionData.getAllExtensionPermissions('reply')); return items; @@ -366,31 +391,6 @@ export default class PermissionGrid { - const minutes = parseInt(app.data.settings.allow_hide_own_posts, 10); - - return SettingDropdown.component({ - defaultLabel: minutes - ? app.translator.trans('core.admin.permissions_controls.allow_some_minutes_button', { count: minutes }) - : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'), - key: 'allow_hide_own_posts', - options: [ - { value: '-1', label: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button') }, - { value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button') }, - { value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button') }, - { value: '0', label: app.translator.trans('core.admin.permissions_controls.allow_never_button') }, - ], - }); - }, - }, - 60 - ); - items.add( 'deletePosts', { diff --git a/framework/core/locale/core.yml b/framework/core/locale/core.yml index 8c61066b47..d32962dd4a 100644 --- a/framework/core/locale/core.yml +++ b/framework/core/locale/core.yml @@ -194,7 +194,7 @@ core: # These translations are used in the Permissions page of the admin interface. permissions: - allow_delete_own_posts_label: Allow deleting own posts + allow_hide_own_posts_label: Allow deleting own posts allow_post_editing_label: Allow post editing allow_renaming_label: Allow renaming create_access_token_label: Create access token diff --git a/framework/core/src/Install/Steps/WriteSettings.php b/framework/core/src/Install/Steps/WriteSettings.php index 18e5bf13f2..c23ca005dc 100644 --- a/framework/core/src/Install/Steps/WriteSettings.php +++ b/framework/core/src/Install/Steps/WriteSettings.php @@ -56,7 +56,7 @@ private function getSettings() private function getDefaults() { return [ - 'allow_delete_own_posts' => 'reply', + 'allow_hide_own_posts' => 'reply', 'allow_post_editing' => 'reply', 'allow_renaming' => '10', 'allow_sign_up' => '1',