Skip to content

Commit 763ce19

Browse files
committed
Update AdminApiController, improve admin moderation tools
1 parent 71ad7d5 commit 763ce19

File tree

3 files changed

+185
-5
lines changed

3 files changed

+185
-5
lines changed

app/Http/Controllers/Api/AdminApiController.php

+145-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,14 @@
2727
use App\Services\ModLogService;
2828
use App\Services\SnowflakeService;
2929
use App\Services\StatusService;
30+
use App\Services\PublicTimelineService;
3031
use App\Services\NetworkTimelineService;
3132
use App\Services\NotificationService;
3233
use App\Http\Resources\AdminInstance;
3334
use App\Http\Resources\AdminUser;
35+
use App\Jobs\DeletePipeline\DeleteAccountPipeline;
36+
use App\Jobs\DeletePipeline\DeleteRemoteProfilePipeline;
37+
use App\Jobs\DeletePipeline\DeleteRemoteStatusPipeline;
3438

3539
class AdminApiController extends Controller
3640
{
@@ -95,7 +99,7 @@ public function autospamHandle(Request $request)
9599
abort_unless($request->user()->is_admin == 1, 404);
96100

97101
$this->validate($request, [
98-
'action' => 'required|in:dismiss,approve,dismiss-all,approve-all',
102+
'action' => 'required|in:dismiss,approve,dismiss-all,approve-all,delete-post,delete-account',
99103
'id' => 'required'
100104
]);
101105

@@ -107,14 +111,53 @@ public function autospamHandle(Request $request)
107111
$now = now();
108112
$res = ['status' => 'success'];
109113
$meta = json_decode($appeal->meta);
114+
$user = $appeal->user;
115+
$profile = $user->profile;
110116

111117
if($action == 'dismiss') {
112118
$appeal->is_spam = true;
113119
$appeal->appeal_handled_at = $now;
114120
$appeal->save();
115121

116-
Cache::forget('pf:bouncer_v0:exemption_by_pid:' . $appeal->user->profile_id);
117-
Cache::forget('pf:bouncer_v0:recent_by_pid:' . $appeal->user->profile_id);
122+
Cache::forget('pf:bouncer_v0:exemption_by_pid:' . $profile->id);
123+
Cache::forget('pf:bouncer_v0:recent_by_pid:' . $profile->id);
124+
Cache::forget('admin-dash:reports:spam-count');
125+
return $res;
126+
}
127+
128+
if($action == 'delete-post') {
129+
$appeal->appeal_handled_at = now();
130+
$appeal->is_spam = true;
131+
$appeal->save();
132+
ModLogService::boot()
133+
->objectUid($profile->id)
134+
->objectId($appeal->status->id)
135+
->objectType('App\Status::class')
136+
->user($request->user())
137+
->action('admin.status.delete')
138+
->accessLevel('admin')
139+
->save();
140+
PublicTimelineService::deleteByProfileId($profile->id);
141+
StatusDelete::dispatch($appeal->status)->onQueue('high');
142+
Cache::forget('admin-dash:reports:spam-count');
143+
return $res;
144+
}
145+
146+
if($action == 'delete-account') {
147+
abort_if($user->is_admin, 400, 'Cannot delete an admin account.');
148+
$appeal->appeal_handled_at = now();
149+
$appeal->is_spam = true;
150+
$appeal->save();
151+
ModLogService::boot()
152+
->objectUid($profile->id)
153+
->objectId($profile->id)
154+
->objectType('App\User::class')
155+
->user($request->user())
156+
->action('admin.user.delete')
157+
->accessLevel('admin')
158+
->save();
159+
PublicTimelineService::deleteByProfileId($profile->id);
160+
DeleteAccountPipeline::dispatch($appeal->user)->onQueue('high');
118161
Cache::forget('admin-dash:reports:spam-count');
119162
return $res;
120163
}
@@ -459,7 +502,7 @@ public function userAdminAction(Request $request)
459502

460503
$this->validate($request, [
461504
'id' => 'required',
462-
'action' => 'required|in:unlisted,cw,no_autolink,refresh_stats,verify_email',
505+
'action' => 'required|in:unlisted,cw,no_autolink,refresh_stats,verify_email,delete',
463506
'value' => 'sometimes'
464507
]);
465508

@@ -470,7 +513,59 @@ public function userAdminAction(Request $request)
470513

471514
abort_if($user->is_admin == true && $action !== 'refresh_stats', 400, 'Cannot moderate admin accounts');
472515

473-
if($action === 'refresh_stats') {
516+
if($action === 'delete') {
517+
if(config('pixelfed.account_deletion') == false) {
518+
abort(404);
519+
}
520+
521+
abort_if($user->is_admin, 400, 'Cannot delete an admin account.');
522+
523+
$ts = now()->addMonth();
524+
525+
$user->status = 'delete';
526+
$user->delete_after = $ts;
527+
$user->save();
528+
529+
$profile->status = 'delete';
530+
$profile->delete_after = $ts;
531+
$profile->save();
532+
533+
ModLogService::boot()
534+
->objectUid($profile->id)
535+
->objectId($profile->id)
536+
->objectType('App\Profile::class')
537+
->user($request->user())
538+
->action('admin.user.delete')
539+
->accessLevel('admin')
540+
->save();
541+
542+
PublicTimelineService::deleteByProfileId($profile->id);
543+
NetworkTimelineService::deleteByProfileId($profile->id);
544+
545+
if($profile->user_id) {
546+
DB::table('oauth_access_tokens')->whereUserId($user->id)->delete();
547+
DB::table('oauth_auth_codes')->whereUserId($user->id)->delete();
548+
$user->email = $user->id;
549+
$user->password = '';
550+
$user->status = 'delete';
551+
$user->save();
552+
$profile->status = 'delete';
553+
$profile->delete_after = now()->addMonth();
554+
$profile->save();
555+
AccountService::del($profile->id);
556+
DeleteAccountPipeline::dispatch($user)->onQueue('high');
557+
} else {
558+
$profile->status = 'delete';
559+
$profile->delete_after = now()->addMonth();
560+
$profile->save();
561+
AccountService::del($profile->id);
562+
DeleteRemoteProfilePipeline::dispatch($profile)->onQueue('high');
563+
}
564+
return [
565+
'status' => 200,
566+
'msg' => 'deleted',
567+
];
568+
} else if($action === 'refresh_stats') {
474569
$profile->following_count = DB::table('followers')->whereProfileId($user->profile_id)->count();
475570
$profile->followers_count = DB::table('followers')->whereFollowingId($user->profile_id)->count();
476571
$statusCount = Status::whereProfileId($user->profile_id)
@@ -496,6 +591,51 @@ public function userAdminAction(Request $request)
496591
])
497592
->accessLevel('admin')
498593
->save();
594+
} else if($action === 'unlisted') {
595+
ModLogService::boot()
596+
->objectUid($profile->id)
597+
->objectId($profile->id)
598+
->objectType('App\Profile::class')
599+
->user($request->user())
600+
->action('admin.user.moderate')
601+
->metadata([
602+
'action' => $action,
603+
'message' => 'Success!'
604+
])
605+
->accessLevel('admin')
606+
->save();
607+
$profile->unlisted = !$profile->unlisted;
608+
$profile->save();
609+
} else if($action === 'cw') {
610+
ModLogService::boot()
611+
->objectUid($profile->id)
612+
->objectId($profile->id)
613+
->objectType('App\Profile::class')
614+
->user($request->user())
615+
->action('admin.user.moderate')
616+
->metadata([
617+
'action' => $action,
618+
'message' => 'Success!'
619+
])
620+
->accessLevel('admin')
621+
->save();
622+
$profile->cw = !$profile->cw;
623+
$profile->save();
624+
} else if($action === 'no_autolink') {
625+
ModLogService::boot()
626+
->objectUid($profile->id)
627+
->objectId($profile->id)
628+
->objectType('App\Profile::class')
629+
->user($request->user())
630+
->action('admin.user.moderate')
631+
->metadata([
632+
'action' => $action,
633+
'message' => 'Success!'
634+
])
635+
->accessLevel('admin')
636+
->save();
637+
$profile->no_autolink = !$profile->no_autolink;
638+
$profile->save();
499639
} else {
500640
$profile->{$action} = filter_var($request->input('value'), FILTER_VALIDATE_BOOLEAN);
501641
$profile->save();

app/Services/NetworkTimelineService.php

+20
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ public static function count()
7272
return Redis::zcard(self::CACHE_KEY);
7373
}
7474

75+
public static function deleteByProfileId($profileId)
76+
{
77+
$res = Redis::zrange(self::CACHE_KEY, 0, '-1');
78+
if(!$res) {
79+
return;
80+
}
81+
foreach($res as $postId) {
82+
$s = StatusService::get($postId);
83+
if(!$s) {
84+
self::rem($postId);
85+
continue;
86+
}
87+
if($s['account']['id'] == $profileId) {
88+
self::rem($postId);
89+
}
90+
}
91+
92+
return;
93+
}
94+
7595
public static function warmCache($force = false, $limit = 100)
7696
{
7797
if(self::count() == 0 || $force == true) {

app/Services/PublicTimelineService.php

+20
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ public static function count()
7272
return Redis::zcard(self::CACHE_KEY);
7373
}
7474

75+
public static function deleteByProfileId($profileId)
76+
{
77+
$res = Redis::zrange(self::CACHE_KEY, 0, '-1');
78+
if(!$res) {
79+
return;
80+
}
81+
foreach($res as $postId) {
82+
$s = StatusService::get($postId);
83+
if(!$s) {
84+
self::rem($postId);
85+
continue;
86+
}
87+
if($s['account']['id'] == $profileId) {
88+
self::rem($postId);
89+
}
90+
}
91+
92+
return;
93+
}
94+
7595
public static function warmCache($force = false, $limit = 100)
7696
{
7797
if(self::count() == 0 || $force == true) {

0 commit comments

Comments
 (0)