feat: add delete own posts permission (#3784)

This commit is contained in:
Tristian Kelly 2023-04-17 02:53:51 -05:00 committed by GitHub
parent 176b5540d8
commit 818a100625
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 139 additions and 2 deletions

View File

@ -288,6 +288,31 @@ export default class PermissionGrid<CustomAttrs extends IPermissionGridAttrs = I
90
);
items.add(
'hideOwnPosts',
{
icon: 'far fa-trash-alt',
label: app.translator.trans('core.admin.permissions.allow_hide_own_posts_label'),
setting: () => {
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;

View File

@ -194,6 +194,7 @@ core:
# These translations are used in the Permissions page of the admin interface.
permissions:
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
@ -228,6 +229,7 @@ core:
# These translations are used in the dropdown menus on the Permissions page.
permissions_controls:
allow_indefinitely_button: Indefinitely
allow_never_button: => 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
@ -489,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 +804,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

View File

@ -56,6 +56,7 @@ class WriteSettings implements Step
private function getDefaults()
{
return [
'allow_hide_own_posts' => 'reply',
'allow_post_editing' => 'reply',
'allow_renaming' => '10',
'allow_sign_up' => '1',

View File

@ -71,6 +71,14 @@ class PostPolicy extends AbstractPolicy
*/
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();
}
}
}
}

View File

@ -121,4 +121,104 @@ class PostPolicyTest extends TestCase
$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));
}
/**
* @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));
}
}