kopia lustrzana https://github.com/pixelfed/pixelfed
				
				
				
			WIP: Implement domain blocks
							rodzic
							
								
									c96167f2f7
								
							
						
					
					
						commit
						652654e24f
					
				| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers\Api;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
 | 
			
		||||
class ApiController extends Controller {
 | 
			
		||||
  public function json($res, $headers = [], $code = 200) {
 | 
			
		||||
    return response()->json($res, $code, $this->filterHeaders($headers), JSON_UNESCAPED_SLASHES);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function linksForCollection($paginator) {
 | 
			
		||||
    $link = null;
 | 
			
		||||
 | 
			
		||||
    if ($paginator->onFirstPage()) {
 | 
			
		||||
      if ($paginator->hasMorePages()) {
 | 
			
		||||
          $link = '<'.$paginator->nextPageUrl().'>; rel="prev"';
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      if ($paginator->previousPageUrl()) {
 | 
			
		||||
          $link = '<'.$paginator->previousPageUrl().'>; rel="next"';
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ($paginator->hasMorePages()) {
 | 
			
		||||
          $link .= ($link ? ', ' : '').'<'.$paginator->nextPageUrl().'>; rel="prev"';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $link;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function filterHeaders($headers) {
 | 
			
		||||
    return array_filter($headers, function($v, $k) {
 | 
			
		||||
      return $v != null;
 | 
			
		||||
    }, ARRAY_FILTER_USE_BOTH);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers\Api\V1\Admin;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Validation\Rule;
 | 
			
		||||
use App\Http\Controllers\Api\ApiController;
 | 
			
		||||
use App\Instance;
 | 
			
		||||
use App\Services\InstanceService;
 | 
			
		||||
use App\Http\Resources\MastoApi\Admin\DomainBlockResource;
 | 
			
		||||
 | 
			
		||||
class DomainBlocksController extends ApiController {
 | 
			
		||||
  public function index(Request $request) {
 | 
			
		||||
    $this->validate($request, [
 | 
			
		||||
      'limit' => 'sometimes|integer|max:100|min:1',
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    $limit = $request->input('limit', 100);
 | 
			
		||||
 | 
			
		||||
    $res = Instance::moderated()
 | 
			
		||||
      ->orderBy('id')
 | 
			
		||||
      ->cursorPaginate($limit)
 | 
			
		||||
      ->withQueryString();
 | 
			
		||||
 | 
			
		||||
    return $this->json(DomainBlockResource::collection($res), [
 | 
			
		||||
      'Link' => $this->linksForCollection($res)
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function show(Request $request, $id) {
 | 
			
		||||
    $res = Instance::moderated()
 | 
			
		||||
      ->findOrFail($id);
 | 
			
		||||
 | 
			
		||||
    return $this->json(new DomainBlockResource($res));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function create(Request $request) {
 | 
			
		||||
    $this->validate($request, [
 | 
			
		||||
      'domain' => 'required|string|min:1|max:120',
 | 
			
		||||
      'severity' => [
 | 
			
		||||
        'sometimes',
 | 
			
		||||
        Rule::in(['noop', 'silence', 'suspend'])
 | 
			
		||||
      ],
 | 
			
		||||
      'reject_media' => 'sometimes|required|boolean',
 | 
			
		||||
      'reject_reports' => 'sometimes|required|boolean',
 | 
			
		||||
      'private_comment' => 'sometimes|string|min:1|max:1000',
 | 
			
		||||
      'public_comment' => 'sometimes|string|min:1|max:1000',
 | 
			
		||||
      'obfuscate' => 'sometimes|required|boolean'
 | 
			
		||||
    ]);
 | 
			
		||||
    
 | 
			
		||||
    $domain = $request->input('domain');
 | 
			
		||||
    $severity = $request->input('severity');
 | 
			
		||||
    $private_comment = $request->input('private_comment');
 | 
			
		||||
 | 
			
		||||
		abort_if(!strpos($domain, '.'), 400, 'Invalid domain');
 | 
			
		||||
		abort_if(!filter_var($domain, FILTER_VALIDATE_DOMAIN), 400, 'Invalid domain');
 | 
			
		||||
 | 
			
		||||
    $existing = Instance::moderated()->whereDomain($domain)->first();
 | 
			
		||||
 | 
			
		||||
    if ($existing) {
 | 
			
		||||
      return $this->json([
 | 
			
		||||
        'error' => 'A domain block already exists for this domain',
 | 
			
		||||
        'existing_domain_block' => new DomainBlockResource($existing)
 | 
			
		||||
      ], [], 422);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $domain_block = Instance::updateOrCreate(
 | 
			
		||||
      [ 'domain' => $domain ],
 | 
			
		||||
      [ 'banned' => $severity === 'suspend', 'unlisted' => $severity === 'silence', 'notes' => [$private_comment]]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    InstanceService::refresh();
 | 
			
		||||
 | 
			
		||||
    return $this->json(new DomainBlockResource($domain_block));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Resources\MastoApi\Admin;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Resources\Json\JsonResource;
 | 
			
		||||
 | 
			
		||||
class DomainBlockResource extends JsonResource
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Transform the resource into an array.
 | 
			
		||||
     *
 | 
			
		||||
     * @return array<string, mixed>
 | 
			
		||||
     */
 | 
			
		||||
    public function toArray(Request $request): array
 | 
			
		||||
    {
 | 
			
		||||
        $severity = 'noop';
 | 
			
		||||
        if ($this->banned) {
 | 
			
		||||
            $severity = 'suspend';
 | 
			
		||||
        } else if ($this->unlisted) {
 | 
			
		||||
            $severity = 'silence';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'id' => $this->id,
 | 
			
		||||
            'domain' => $this->domain,
 | 
			
		||||
            'severity' => $severity,
 | 
			
		||||
            // Using the updated_at value as this is going to be the closest to
 | 
			
		||||
            // when the domain was banned
 | 
			
		||||
            'created_at' => $this->updated_at,
 | 
			
		||||
            // We don't have data for these fields
 | 
			
		||||
            'reject_media' => false,
 | 
			
		||||
            'reject_reports' => false,
 | 
			
		||||
            'private_comment' => $this->notes ? join('; ', $this->notes) : null,
 | 
			
		||||
            'public_comment' => $this->limit_reason,
 | 
			
		||||
            'obfuscate' => false
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,13 @@ class Instance extends Model
 | 
			
		|||
        'notes'
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // To get all moderated instances, we need to search where (banned OR unlisted)
 | 
			
		||||
    public function scopeModerated($query): void {
 | 
			
		||||
        $query->where(function ($query) {
 | 
			
		||||
            $query->where('banned', true)->orWhere('unlisted', true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function profiles()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasMany(Profile::class, 'domain', 'domain');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,6 +101,12 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
 | 
			
		|||
 | 
			
		||||
        Route::get('statuses/{id}/history', 'StatusEditController@history')->middleware($middleware);
 | 
			
		||||
        Route::put('statuses/{id}', 'StatusEditController@store')->middleware($middleware);
 | 
			
		||||
 | 
			
		||||
        Route::group(['prefix' => 'admin'], function() use($middleware) {
 | 
			
		||||
            Route::get('domain_blocks', 'Api\V1\Admin\DomainBlocksController@index')->middleware($middleware);
 | 
			
		||||
            Route::post('domain_blocks', 'Api\V1\Admin\DomainBlocksController@create')->middleware($middleware);
 | 
			
		||||
            Route::get('domain_blocks/{id}', 'Api\V1\Admin\DomainBlocksController@show')->middleware($middleware);
 | 
			
		||||
        })->middleware($middleware);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    Route::group(['prefix' => 'v2'], function() use($middleware) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue