GroupFederationController.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\Group;
  4. use App\Models\GroupPost;
  5. use App\Models\InstanceActor;
  6. use App\Services\MediaService;
  7. use App\Status;
  8. use App\Util\Lexer\Autolink;
  9. use Illuminate\Http\Request;
  10. use Illuminate\Support\Facades\Cache;
  11. class GroupFederationController extends Controller
  12. {
  13. public function getGroupObject(Request $request, $id)
  14. {
  15. $group = Group::whereLocal(true)->whereActivitypub(true)->findOrFail($id);
  16. $res = $this->showGroupObject($group);
  17. return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  18. }
  19. public function showGroupObject($group)
  20. {
  21. return Cache::remember('ap:groups:object:'.$group->id, 3600, function () use ($group) {
  22. return [
  23. '@context' => 'https://www.w3.org/ns/activitystreams',
  24. 'id' => $group->url(),
  25. 'inbox' => $group->permalink('/inbox'),
  26. 'name' => $group->name,
  27. 'outbox' => $group->permalink('/outbox'),
  28. 'summary' => $group->description,
  29. 'type' => 'Group',
  30. 'attributedTo' => [
  31. 'type' => 'Person',
  32. 'id' => $group->admin->permalink(),
  33. ],
  34. // 'endpoints' => [
  35. // 'sharedInbox' => config('app.url') . '/f/inbox'
  36. // ],
  37. 'preferredUsername' => 'gid_'.$group->id,
  38. 'publicKey' => [
  39. 'id' => $group->permalink('#main-key'),
  40. 'owner' => $group->permalink(),
  41. 'publicKeyPem' => InstanceActor::first()->public_key,
  42. ],
  43. 'url' => $group->permalink(),
  44. ];
  45. if ($group->metadata && isset($group->metadata['avatar'])) {
  46. $res['icon'] = [
  47. 'type' => 'Image',
  48. 'url' => $group->metadata['avatar']['url'],
  49. ];
  50. }
  51. if ($group->metadata && isset($group->metadata['header'])) {
  52. $res['image'] = [
  53. 'type' => 'Image',
  54. 'url' => $group->metadata['header']['url'],
  55. ];
  56. }
  57. ksort($res);
  58. return $res;
  59. });
  60. }
  61. public function getStatusObject(Request $request, $gid, $sid)
  62. {
  63. $group = Group::whereLocal(true)->whereActivitypub(true)->findOrFail($gid);
  64. $gp = GroupPost::whereGroupId($gid)->findOrFail($sid);
  65. $status = Status::findOrFail($gp->status_id);
  66. // permission check
  67. $content = $status->caption ? Autolink::create()->autolink($status->caption) : null;
  68. $res = [
  69. '@context' => 'https://www.w3.org/ns/activitystreams',
  70. 'id' => $gp->url(),
  71. 'type' => 'Note',
  72. 'summary' => null,
  73. 'content' => $content,
  74. 'inReplyTo' => null,
  75. 'published' => $status->created_at->toAtomString(),
  76. 'url' => $gp->url(),
  77. 'attributedTo' => $status->profile->permalink(),
  78. 'to' => [
  79. 'https://www.w3.org/ns/activitystreams#Public',
  80. $group->permalink('/followers'),
  81. ],
  82. 'cc' => [],
  83. 'sensitive' => (bool) $status->is_nsfw,
  84. 'attachment' => MediaService::activitypub($status->id),
  85. 'target' => [
  86. 'type' => 'Collection',
  87. 'id' => $group->permalink('/wall'),
  88. 'attributedTo' => $group->permalink(),
  89. ],
  90. ];
  91. // ksort($res);
  92. return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  93. }
  94. }