Update ApiV1Controller, handle Moved accounts

This commit is contained in:
Daniel Supernault 2024-09-11 02:47:34 -06:00
parent 0d8c142bf3
commit 6c48a12423
No known key found for this signature in database
GPG key ID: 23740873EE6F76A1
2 changed files with 59 additions and 36 deletions

View file

@ -67,9 +67,7 @@ use App\Transformer\Api\Mastodon\v1\AccountTransformer;
use App\Transformer\Api\Mastodon\v1\MediaTransformer;
use App\Transformer\Api\Mastodon\v1\NotificationTransformer;
use App\Transformer\Api\Mastodon\v1\StatusTransformer;
use App\Transformer\Api\{
RelationshipTransformer,
};
use App\Transformer\Api\RelationshipTransformer;
use App\User;
use App\UserFilter;
use App\UserSetting;
@ -98,8 +96,8 @@ class ApiV1Controller extends Controller
public function __construct()
{
$this->fractal = new Fractal\Manager();
$this->fractal->setSerializer(new ArraySerializer());
$this->fractal = new Fractal\Manager;
$this->fractal->setSerializer(new ArraySerializer);
}
public function json($res, $code = 200, $headers = [])
@ -490,6 +488,7 @@ class ApiV1Controller extends Controller
$account = AccountService::get($id);
abort_if(! $account, 404);
abort_if(isset($account['moved'], $account['moved']['id']), 404, 'Account moved');
$pid = $request->user()->profile_id;
$this->validate($request, [
'limit' => 'sometimes|integer|min:1',
@ -591,6 +590,7 @@ class ApiV1Controller extends Controller
$account = AccountService::get($id);
abort_if(! $account, 404);
abort_if(isset($account['moved'], $account['moved']['id']), 404, 'Account moved');
$pid = $request->user()->profile_id;
$this->validate($request, [
'limit' => 'sometimes|integer|min:1',
@ -818,6 +818,8 @@ class ApiV1Controller extends Controller
->whereNull('status')
->findOrFail($id);
abort_if($target && $target->moved_to_profile_id, 400, 'Cannot follow an account that has moved!');
if ($target && $target->domain) {
$domain = $target->domain;
abort_if(in_array($domain, InstanceService::getBannedDomains()), 404);
@ -857,7 +859,7 @@ class ApiV1Controller extends Controller
'following_id' => $target->id,
]);
if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
(new FollowerController())->sendFollow($user->profile, $target);
(new FollowerController)->sendFollow($user->profile, $target);
}
} else {
$follower = Follower::firstOrCreate([
@ -866,7 +868,7 @@ class ApiV1Controller extends Controller
]);
if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
(new FollowerController())->sendFollow($user->profile, $target);
(new FollowerController)->sendFollow($user->profile, $target);
}
FollowPipeline::dispatch($follower)->onQueue('high');
}
@ -925,7 +927,7 @@ class ApiV1Controller extends Controller
$followRequest->delete();
RelationshipService::refresh($target->id, $user->profile_id);
}
$resource = new Fractal\Resource\Item($target, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($target, new RelationshipTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -938,7 +940,7 @@ class ApiV1Controller extends Controller
UnfollowPipeline::dispatch($user->profile_id, $target->id)->onQueue('high');
if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
(new FollowerController())->sendUndoFollow($user->profile, $target);
(new FollowerController)->sendUndoFollow($user->profile, $target);
}
RelationshipService::refresh($user->profile_id, $target->id);
@ -1132,6 +1134,8 @@ class ApiV1Controller extends Controller
$profile = Profile::findOrFail($id);
abort_if($profile->moved_to_profile_id, 422, 'Cannot block an account that has migrated!');
if ($profile->user && $profile->user->is_admin == true) {
abort(400, 'You cannot block an admin');
}
@ -1198,7 +1202,7 @@ class ApiV1Controller extends Controller
UserFilterService::block($pid, $id);
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -1225,6 +1229,8 @@ class ApiV1Controller extends Controller
$profile = Profile::findOrFail($id);
abort_if($profile->moved_to_profile_id, 422, 'Cannot unblock an account that has migrated!');
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($profile->id)
->whereFilterableType('App\Profile')
@ -1237,7 +1243,7 @@ class ApiV1Controller extends Controller
}
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -1372,6 +1378,8 @@ class ApiV1Controller extends Controller
abort_unless($status, 404);
abort_if(isset($status['moved'], $status['moved']['id']), 422, 'Cannot like a post from an account that has migrated');
if ($status && isset($status['account'], $status['account']['acct']) && strpos($status['account']['acct'], '@') != -1) {
$domain = parse_url($status['account']['url'], PHP_URL_HOST);
abort_if(in_array($domain, InstanceService::getBannedDomains()), 404);
@ -1440,6 +1448,7 @@ class ApiV1Controller extends Controller
$status = $napi ? StatusService::get($id, false) : StatusService::getMastodon($id, false);
abort_unless($status && isset($status['account']), 404);
abort_if(isset($status['moved'], $status['moved']['id']), 422, 'Cannot unlike a post from an account that has migrated');
if ($status && isset($status['account'], $status['account']['acct']) && strpos($status['account']['acct'], '@') != -1) {
$domain = parse_url($status['account']['url'], PHP_URL_HOST);
@ -1540,6 +1549,8 @@ class ApiV1Controller extends Controller
$pid = $request->user()->profile_id;
$target = AccountService::getMastodon($id);
abort_if(isset($target['moved'], $target['moved']['id']), 422, 'Cannot accept a request from an account that has migrated!');
if (! $target) {
return response()->json(['error' => 'Record not found'], 404);
}
@ -1556,7 +1567,7 @@ class ApiV1Controller extends Controller
}
$follower = $followRequest->follower;
$follow = new Follower();
$follow = new Follower;
$follow->profile_id = $follower->id;
$follow->following_id = $pid;
$follow->save();
@ -1603,6 +1614,8 @@ class ApiV1Controller extends Controller
return response()->json(['error' => 'Record not found'], 404);
}
abort_if(isset($target['moved'], $target['moved']['id']), 422, 'Cannot reject a request from an account that has migrated!');
$followRequest = FollowRequest::whereFollowingId($pid)->whereFollowerId($id)->first();
if (! $followRequest) {
@ -1661,7 +1674,7 @@ class ApiV1Controller extends Controller
null;
});
$stats = Cache::remember('api:v1:instance-data:stats', 43200, function () {
$stats = Cache::remember('api:v1:instance-data:stats:v0', 43200, function () {
return [
'user_count' => (int) User::count(),
'status_count' => (int) StatusService::totalLocalStatuses(),
@ -1857,7 +1870,7 @@ class ApiV1Controller extends Controller
abort_if(MediaBlocklistService::exists($hash) == true, 451);
$media = new Media();
$media = new Media;
$media->status_id = null;
$media->profile_id = $profile->id;
$media->user_id = $user->id;
@ -1891,7 +1904,7 @@ class ApiV1Controller extends Controller
$user->save();
Cache::forget($limitKey);
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
$resource = new Fractal\Resource\Item($media, new MediaTransformer);
$res = $this->fractal->createData($resource)->toArray();
$res['preview_url'] = $media->url().'?v='.time();
$res['url'] = $media->url().'?v='.time();
@ -1946,9 +1959,9 @@ class ApiV1Controller extends Controller
], 429);
}
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
$fractal = new Fractal\Manager;
$fractal->setSerializer(new ArraySerializer);
$resource = new Fractal\Resource\Item($media, new MediaTransformer);
return $this->json($fractal->createData($resource)->toArray());
}
@ -1972,7 +1985,7 @@ class ApiV1Controller extends Controller
->whereNull('status_id')
->findOrFail($id);
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
$resource = new Fractal\Resource\Item($media, new MediaTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -2085,7 +2098,7 @@ class ApiV1Controller extends Controller
}
}
$media = new Media();
$media = new Media;
$media->status_id = null;
$media->profile_id = $profile->id;
$media->user_id = $user->id;
@ -2119,7 +2132,7 @@ class ApiV1Controller extends Controller
$user->save();
Cache::forget($limitKey);
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
$resource = new Fractal\Resource\Item($media, new MediaTransformer);
$res = $this->fractal->createData($resource)->toArray();
$res['preview_url'] = $media->url().'?v='.time();
$res['url'] = null;
@ -2204,6 +2217,8 @@ class ApiV1Controller extends Controller
$account = Profile::findOrFail($id);
abort_if($account->moved_to_profile_id, 422, 'Cannot mute an account that has migrated!');
if ($account && $account->domain) {
$domain = $account->domain;
abort_if(in_array($domain, InstanceService::getBannedDomains()), 404);
@ -2237,7 +2252,7 @@ class ApiV1Controller extends Controller
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -2263,6 +2278,8 @@ class ApiV1Controller extends Controller
$profile = Profile::findOrFail($id);
abort_if($profile->moved_to_profile_id, 422, 'Cannot unmute an account that has migrated!');
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($profile->id)
->whereFilterableType('App\Profile')
@ -2276,7 +2293,7 @@ class ApiV1Controller extends Controller
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer);
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
@ -3209,6 +3226,7 @@ class ApiV1Controller extends Controller
$status = Status::findOrFail($id);
$account = AccountService::get($status->profile_id, true);
abort_if(! $account, 404);
abort_if(isset($account['moved'], $account['moved']['id']), 404, 'Account moved');
if ($account && strpos($account['acct'], '@') != -1) {
$domain = parse_url($account['url'], PHP_URL_HOST);
abort_if(in_array($domain, InstanceService::getBannedDomains()), 404);
@ -3308,11 +3326,12 @@ class ApiV1Controller extends Controller
$pid = $user->profile_id;
$status = Status::findOrFail($id);
$account = AccountService::get($status->profile_id, true);
abort_if(! $account, 404);
abort_if(isset($account['moved'], $account['moved']['id']), 404, 'Account moved');
if ($account && strpos($account['acct'], '@') != -1) {
$domain = parse_url($account['url'], PHP_URL_HOST);
abort_if(in_array($domain, InstanceService::getBannedDomains()), 404);
}
abort_if(! $account, 404);
$author = intval($status->profile_id) === intval($pid) || $user->is_admin;
$napi = $request->has(self::PF_API_ENTITY_KEY);
@ -3617,7 +3636,7 @@ class ApiV1Controller extends Controller
$status = Status::whereProfileId($request->user()->profile->id)
->findOrFail($id);
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
$resource = new Fractal\Resource\Item($status, new StatusTransformer);
Cache::forget('profile:status_count:'.$status->profile_id);
StatusDelete::dispatch($status);
@ -3644,6 +3663,8 @@ class ApiV1Controller extends Controller
abort_if($user->has_roles && ! UserRoleService::can('can-share', $user->id), 403, 'Invalid permissions for this action');
AccountService::setLastActive($user->id);
$status = Status::whereScope('public')->findOrFail($id);
$account = AccountService::get($status->profile_id);
abort_if(isset($account['moved'], $account['moved']['id']), 422, 'Cannot share a post from an account that has migrated');
if ($status && ($status->uri || $status->url || $status->object_url)) {
$url = $status->uri ?? $status->url ?? $status->object_url;
$domain = parse_url($url, PHP_URL_HOST);
@ -3696,6 +3717,8 @@ class ApiV1Controller extends Controller
abort_if($user->has_roles && ! UserRoleService::can('can-share', $user->id), 403, 'Invalid permissions for this action');
AccountService::setLastActive($user->id);
$status = Status::whereScope('public')->findOrFail($id);
$account = AccountService::get($status->profile_id);
abort_if(isset($account['moved'], $account['moved']['id']), 422, 'Cannot unshare a post from an account that has migrated');
if (intval($status->profile_id) !== intval($user->profile_id)) {
if ($status->scope == 'private') {
@ -3929,7 +3952,8 @@ class ApiV1Controller extends Controller
$status = Status::findOrFail($id);
$pid = $request->user()->profile_id;
$account = AccountService::get($status->profile_id);
abort_if(isset($account['moved'], $account['moved']['id']), 422, 'Cannot bookmark a post from an account that has migrated');
abort_if($user->has_roles && ! UserRoleService::can('can-bookmark', $user->id), 403, 'Invalid permissions for this action');
abort_if($status->in_reply_to_id || $status->reblog_of_id, 404);
abort_if(! in_array($status->scope, ['public', 'unlisted', 'private']), 404);
@ -4045,8 +4069,8 @@ class ApiV1Controller extends Controller
}
$pid = $request->user()->profile_id;
$status = StatusService::getMastodon($id, false);
abort_if(! $status, 404);
abort_if(isset($status['account'], $account['account']['moved']['id']), 404, 'Account moved');
if ($status['visibility'] == 'private') {
if ($pid != $status['account']['id']) {
@ -4135,11 +4159,11 @@ class ApiV1Controller extends Controller
{
abort_if(! $request->user(), 403);
$status = Status::findOrFail($id);
$pid = $request->user()->profile_id;
abort_if(! in_array($status->scope, ['public', 'unlisted', 'private']), 404);
$status = StatusService::get($id, false, true);
abort_if(! $status, 404);
abort_if(! in_array($status['visibility'], ['public', 'unlisted', 'private']), 404);
return $this->json(StatusService::getState($status->id, $pid));
return $this->json(StatusService::getState($status['id'], $request->user()->profile_id));
}
/**

View file

@ -24,13 +24,13 @@ class AccountService
public static function get($id, $softFail = false)
{
$res = Cache::remember(self::CACHE_KEY.$id, 43200, function () use ($id) {
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$fractal = new Fractal\Manager;
$fractal->setSerializer(new ArraySerializer);
$profile = Profile::find($id);
if (! $profile || $profile->status === 'delete') {
return null;
}
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
$resource = new Fractal\Resource\Item($profile, new AccountTransformer);
return $fractal->createData($resource)->toArray();
});
@ -202,7 +202,7 @@ class AccountService
}
$count = Status::whereProfileId($id)
->whereNull(['in_reply_to_id','reblog_of_id'])
->whereNull(['in_reply_to_id', 'reblog_of_id'])
->whereIn('scope', ['public', 'unlisted', 'private'])
->count();
@ -291,7 +291,6 @@ class AccountService
$user->save();
Cache::put($key, 1, 14400);
}
}
public static function blocksDomain($pid, $domain = false)