mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 14:31:26 +00:00
Update AdminApiController, improve admin moderation tools
This commit is contained in:
parent
71ad7d5d43
commit
763ce19a0a
3 changed files with 185 additions and 5 deletions
|
@ -27,10 +27,14 @@ use App\Services\InstanceService;
|
|||
use App\Services\ModLogService;
|
||||
use App\Services\SnowflakeService;
|
||||
use App\Services\StatusService;
|
||||
use App\Services\PublicTimelineService;
|
||||
use App\Services\NetworkTimelineService;
|
||||
use App\Services\NotificationService;
|
||||
use App\Http\Resources\AdminInstance;
|
||||
use App\Http\Resources\AdminUser;
|
||||
use App\Jobs\DeletePipeline\DeleteAccountPipeline;
|
||||
use App\Jobs\DeletePipeline\DeleteRemoteProfilePipeline;
|
||||
use App\Jobs\DeletePipeline\DeleteRemoteStatusPipeline;
|
||||
|
||||
class AdminApiController extends Controller
|
||||
{
|
||||
|
@ -95,7 +99,7 @@ class AdminApiController extends Controller
|
|||
abort_unless($request->user()->is_admin == 1, 404);
|
||||
|
||||
$this->validate($request, [
|
||||
'action' => 'required|in:dismiss,approve,dismiss-all,approve-all',
|
||||
'action' => 'required|in:dismiss,approve,dismiss-all,approve-all,delete-post,delete-account',
|
||||
'id' => 'required'
|
||||
]);
|
||||
|
||||
|
@ -107,14 +111,53 @@ class AdminApiController extends Controller
|
|||
$now = now();
|
||||
$res = ['status' => 'success'];
|
||||
$meta = json_decode($appeal->meta);
|
||||
$user = $appeal->user;
|
||||
$profile = $user->profile;
|
||||
|
||||
if($action == 'dismiss') {
|
||||
$appeal->is_spam = true;
|
||||
$appeal->appeal_handled_at = $now;
|
||||
$appeal->save();
|
||||
|
||||
Cache::forget('pf:bouncer_v0:exemption_by_pid:' . $appeal->user->profile_id);
|
||||
Cache::forget('pf:bouncer_v0:recent_by_pid:' . $appeal->user->profile_id);
|
||||
Cache::forget('pf:bouncer_v0:exemption_by_pid:' . $profile->id);
|
||||
Cache::forget('pf:bouncer_v0:recent_by_pid:' . $profile->id);
|
||||
Cache::forget('admin-dash:reports:spam-count');
|
||||
return $res;
|
||||
}
|
||||
|
||||
if($action == 'delete-post') {
|
||||
$appeal->appeal_handled_at = now();
|
||||
$appeal->is_spam = true;
|
||||
$appeal->save();
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($appeal->status->id)
|
||||
->objectType('App\Status::class')
|
||||
->user($request->user())
|
||||
->action('admin.status.delete')
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
PublicTimelineService::deleteByProfileId($profile->id);
|
||||
StatusDelete::dispatch($appeal->status)->onQueue('high');
|
||||
Cache::forget('admin-dash:reports:spam-count');
|
||||
return $res;
|
||||
}
|
||||
|
||||
if($action == 'delete-account') {
|
||||
abort_if($user->is_admin, 400, 'Cannot delete an admin account.');
|
||||
$appeal->appeal_handled_at = now();
|
||||
$appeal->is_spam = true;
|
||||
$appeal->save();
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($profile->id)
|
||||
->objectType('App\User::class')
|
||||
->user($request->user())
|
||||
->action('admin.user.delete')
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
PublicTimelineService::deleteByProfileId($profile->id);
|
||||
DeleteAccountPipeline::dispatch($appeal->user)->onQueue('high');
|
||||
Cache::forget('admin-dash:reports:spam-count');
|
||||
return $res;
|
||||
}
|
||||
|
@ -459,7 +502,7 @@ class AdminApiController extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'id' => 'required',
|
||||
'action' => 'required|in:unlisted,cw,no_autolink,refresh_stats,verify_email',
|
||||
'action' => 'required|in:unlisted,cw,no_autolink,refresh_stats,verify_email,delete',
|
||||
'value' => 'sometimes'
|
||||
]);
|
||||
|
||||
|
@ -470,7 +513,59 @@ class AdminApiController extends Controller
|
|||
|
||||
abort_if($user->is_admin == true && $action !== 'refresh_stats', 400, 'Cannot moderate admin accounts');
|
||||
|
||||
if($action === 'refresh_stats') {
|
||||
if($action === 'delete') {
|
||||
if(config('pixelfed.account_deletion') == false) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
abort_if($user->is_admin, 400, 'Cannot delete an admin account.');
|
||||
|
||||
$ts = now()->addMonth();
|
||||
|
||||
$user->status = 'delete';
|
||||
$user->delete_after = $ts;
|
||||
$user->save();
|
||||
|
||||
$profile->status = 'delete';
|
||||
$profile->delete_after = $ts;
|
||||
$profile->save();
|
||||
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($profile->id)
|
||||
->objectType('App\Profile::class')
|
||||
->user($request->user())
|
||||
->action('admin.user.delete')
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
|
||||
PublicTimelineService::deleteByProfileId($profile->id);
|
||||
NetworkTimelineService::deleteByProfileId($profile->id);
|
||||
|
||||
if($profile->user_id) {
|
||||
DB::table('oauth_access_tokens')->whereUserId($user->id)->delete();
|
||||
DB::table('oauth_auth_codes')->whereUserId($user->id)->delete();
|
||||
$user->email = $user->id;
|
||||
$user->password = '';
|
||||
$user->status = 'delete';
|
||||
$user->save();
|
||||
$profile->status = 'delete';
|
||||
$profile->delete_after = now()->addMonth();
|
||||
$profile->save();
|
||||
AccountService::del($profile->id);
|
||||
DeleteAccountPipeline::dispatch($user)->onQueue('high');
|
||||
} else {
|
||||
$profile->status = 'delete';
|
||||
$profile->delete_after = now()->addMonth();
|
||||
$profile->save();
|
||||
AccountService::del($profile->id);
|
||||
DeleteRemoteProfilePipeline::dispatch($profile)->onQueue('high');
|
||||
}
|
||||
return [
|
||||
'status' => 200,
|
||||
'msg' => 'deleted',
|
||||
];
|
||||
} else if($action === 'refresh_stats') {
|
||||
$profile->following_count = DB::table('followers')->whereProfileId($user->profile_id)->count();
|
||||
$profile->followers_count = DB::table('followers')->whereFollowingId($user->profile_id)->count();
|
||||
$statusCount = Status::whereProfileId($user->profile_id)
|
||||
|
@ -496,6 +591,51 @@ class AdminApiController extends Controller
|
|||
])
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
} else if($action === 'unlisted') {
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($profile->id)
|
||||
->objectType('App\Profile::class')
|
||||
->user($request->user())
|
||||
->action('admin.user.moderate')
|
||||
->metadata([
|
||||
'action' => $action,
|
||||
'message' => 'Success!'
|
||||
])
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
$profile->unlisted = !$profile->unlisted;
|
||||
$profile->save();
|
||||
} else if($action === 'cw') {
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($profile->id)
|
||||
->objectType('App\Profile::class')
|
||||
->user($request->user())
|
||||
->action('admin.user.moderate')
|
||||
->metadata([
|
||||
'action' => $action,
|
||||
'message' => 'Success!'
|
||||
])
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
$profile->cw = !$profile->cw;
|
||||
$profile->save();
|
||||
} else if($action === 'no_autolink') {
|
||||
ModLogService::boot()
|
||||
->objectUid($profile->id)
|
||||
->objectId($profile->id)
|
||||
->objectType('App\Profile::class')
|
||||
->user($request->user())
|
||||
->action('admin.user.moderate')
|
||||
->metadata([
|
||||
'action' => $action,
|
||||
'message' => 'Success!'
|
||||
])
|
||||
->accessLevel('admin')
|
||||
->save();
|
||||
$profile->no_autolink = !$profile->no_autolink;
|
||||
$profile->save();
|
||||
} else {
|
||||
$profile->{$action} = filter_var($request->input('value'), FILTER_VALIDATE_BOOLEAN);
|
||||
$profile->save();
|
||||
|
|
|
@ -72,6 +72,26 @@ class NetworkTimelineService
|
|||
return Redis::zcard(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
public static function deleteByProfileId($profileId)
|
||||
{
|
||||
$res = Redis::zrange(self::CACHE_KEY, 0, '-1');
|
||||
if(!$res) {
|
||||
return;
|
||||
}
|
||||
foreach($res as $postId) {
|
||||
$s = StatusService::get($postId);
|
||||
if(!$s) {
|
||||
self::rem($postId);
|
||||
continue;
|
||||
}
|
||||
if($s['account']['id'] == $profileId) {
|
||||
self::rem($postId);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static function warmCache($force = false, $limit = 100)
|
||||
{
|
||||
if(self::count() == 0 || $force == true) {
|
||||
|
|
|
@ -72,6 +72,26 @@ class PublicTimelineService {
|
|||
return Redis::zcard(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
public static function deleteByProfileId($profileId)
|
||||
{
|
||||
$res = Redis::zrange(self::CACHE_KEY, 0, '-1');
|
||||
if(!$res) {
|
||||
return;
|
||||
}
|
||||
foreach($res as $postId) {
|
||||
$s = StatusService::get($postId);
|
||||
if(!$s) {
|
||||
self::rem($postId);
|
||||
continue;
|
||||
}
|
||||
if($s['account']['id'] == $profileId) {
|
||||
self::rem($postId);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static function warmCache($force = false, $limit = 100)
|
||||
{
|
||||
if(self::count() == 0 || $force == true) {
|
||||
|
|
Loading…
Reference in a new issue