DomainBlocksController.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace App\Http\Controllers\Api\V1\Admin;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Validation\Rule;
  5. use App\Http\Controllers\Api\ApiController;
  6. use App\Instance;
  7. use App\Services\InstanceService;
  8. use App\Http\Resources\MastoApi\Admin\DomainBlockResource;
  9. class DomainBlocksController extends ApiController {
  10. public function __construct() {
  11. $this->middleware(['auth:api', 'api.admin', 'scope:admin:read,admin:read:domain_blocks'])->only(['index', 'show']);
  12. $this->middleware(['auth:api', 'api.admin', 'scope:admin:write,admin:write:domain_blocks'])->only(['create', 'update', 'delete']);
  13. }
  14. public function index(Request $request) {
  15. $this->validate($request, [
  16. 'limit' => 'sometimes|integer|max:100|min:1',
  17. ]);
  18. $limit = $request->input('limit', 100);
  19. $res = Instance::moderated()
  20. ->orderBy('id')
  21. ->cursorPaginate($limit)
  22. ->withQueryString();
  23. return $this->json(DomainBlockResource::collection($res), [
  24. 'Link' => $this->linksForCollection($res)
  25. ]);
  26. }
  27. public function show(Request $request, $id) {
  28. $domain_block = Instance::moderated()->find($id);
  29. if (!$domain_block) {
  30. return $this->json([ 'error' => 'Record not found'], [], 404);
  31. }
  32. return $this->json(new DomainBlockResource($domain_block));
  33. }
  34. public function create(Request $request) {
  35. $this->validate($request, [
  36. 'domain' => 'required|string|min:1|max:120',
  37. 'severity' => [
  38. 'sometimes',
  39. Rule::in(['noop', 'silence', 'suspend'])
  40. ],
  41. 'reject_media' => 'sometimes|required|boolean',
  42. 'reject_reports' => 'sometimes|required|boolean',
  43. 'private_comment' => 'sometimes|string|min:1|max:1000',
  44. 'public_comment' => 'sometimes|string|min:1|max:1000',
  45. 'obfuscate' => 'sometimes|required|boolean'
  46. ]);
  47. $domain = $request->input('domain');
  48. $severity = $request->input('severity');
  49. $private_comment = $request->input('private_comment');
  50. abort_if(!strpos($domain, '.'), 400, 'Invalid domain');
  51. abort_if(!filter_var($domain, FILTER_VALIDATE_DOMAIN), 400, 'Invalid domain');
  52. $parts = explode('.', $domain);
  53. if ($parts[0] == '*') {
  54. // If we only have two parts, e.g., "*", "example", then we want to fail:
  55. abort_if(count($parts) <= 2, 400, 'Invalid domain: This API does not support wildcard domain blocks yet');
  56. // Otherwise we convert the *.foo.example to foo.example
  57. $domain = implode('.', array_slice($parts, 1));
  58. }
  59. // Double check we definitely haven't let anything through:
  60. abort_if(str_contains($domain, '*'), 400, 'Invalid domain');
  61. $existing_domain_block = Instance::moderated()->whereDomain($domain)->first();
  62. if ($existing_domain_block) {
  63. return $this->json([
  64. 'error' => 'A domain block already exists for this domain',
  65. 'existing_domain_block' => new DomainBlockResource($existing_domain_block)
  66. ], [], 422);
  67. }
  68. $domain_block = Instance::updateOrCreate(
  69. [ 'domain' => $domain ],
  70. [ 'banned' => $severity === 'suspend', 'unlisted' => $severity === 'silence', 'notes' => [$private_comment]]
  71. );
  72. InstanceService::refresh();
  73. return $this->json(new DomainBlockResource($domain_block));
  74. }
  75. public function update(Request $request, $id) {
  76. $this->validate($request, [
  77. 'severity' => [
  78. 'sometimes',
  79. Rule::in(['noop', 'silence', 'suspend'])
  80. ],
  81. 'reject_media' => 'sometimes|required|boolean',
  82. 'reject_reports' => 'sometimes|required|boolean',
  83. 'private_comment' => 'sometimes|string|min:1|max:1000',
  84. 'public_comment' => 'sometimes|string|min:1|max:1000',
  85. 'obfuscate' => 'sometimes|required|boolean'
  86. ]);
  87. $severity = $request->input('severity');
  88. $private_comment = $request->input('private_comment');
  89. $domain_block = Instance::moderated()->find($id);
  90. if (!$domain_block) {
  91. return $this->json([ 'error' => 'Record not found'], [], 404);
  92. }
  93. $domain_block->banned = $severity === 'suspend';
  94. $domain_block->unlisted = $severity === 'silence';
  95. $domain_block->notes = [$private_comment];
  96. $domain_block->save();
  97. InstanceService::refresh();
  98. return $this->json(new DomainBlockResource($domain_block));
  99. }
  100. public function delete(Request $request, $id) {
  101. $domain_block = Instance::moderated()->find($id);
  102. if (!$domain_block) {
  103. return $this->json([ 'error' => 'Record not found'], [], 404);
  104. }
  105. $domain_block->banned = false;
  106. $domain_block->unlisted = false;
  107. $domain_block->save();
  108. InstanceService::refresh();
  109. return $this->json(null, [], 200);
  110. }
  111. }