GroupFederationController.php 2.8 KB

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