Skip to content

Commit

Permalink
fix: external lists routes were moved from api middleware (#742)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyrch authored Sep 10, 2024
1 parent 2e0e411 commit eeff29b
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 98 deletions.
15 changes: 15 additions & 0 deletions app/Constants/Config/ApiConstants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace App\Constants\Config;

/**
* Class ApiConstants.
*/
class ApiConstants
{
final public const PATH_QUALIFIED = 'api.path';

final public const URL_QUALIFIED = 'api.url';
}

This file was deleted.

4 changes: 2 additions & 2 deletions app/Http/Api/Schema/List/External/ExternalEntrySchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace App\Http\Api\Schema\List\External;

use App\Http\Api\Field\Base\IdField;
use App\Http\Api\Field\Field;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryAnimeIdField;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryExternalProfileIdField;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryWatchStatusField;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryIdField;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryIsFavoriteField;
use App\Http\Api\Field\List\ExternalProfile\ExternalEntry\ExternalEntryScoreField;
use App\Http\Api\Include\AllowedInclude;
Expand Down Expand Up @@ -58,7 +58,7 @@ public function fields(): array
return array_merge(
parent::fields(),
[
new ExternalEntryIdField($this),
new IdField($this, ExternalEntry::ATTRIBUTE_ID),
new ExternalEntryScoreField($this),
new ExternalEntryIsFavoriteField($this),
new ExternalEntryWatchStatusField($this),
Expand Down
15 changes: 12 additions & 3 deletions app/Http/Api/Schema/List/ExternalProfileSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace App\Http\Api\Schema\List;

use App\Contracts\Http\Api\Schema\SearchableSchema;
use App\Http\Api\Field\Base\IdField;
use App\Http\Api\Field\Field;
use App\Http\Api\Field\List\ExternalProfile\ExternalProfileNameField;
use App\Http\Api\Field\List\ExternalProfile\ExternalProfileIdField;
use App\Http\Api\Field\List\ExternalProfile\ExternalProfileVisibilityField;
use App\Http\Api\Field\List\ExternalProfile\ExternalProfileSiteField;
use App\Http\Api\Field\List\ExternalProfile\ExternalProfileUserIdField;
Expand All @@ -16,6 +16,10 @@
use App\Http\Api\Schema\EloquentSchema;
use App\Http\Api\Schema\List\External\ExternalEntrySchema;
use App\Http\Api\Schema\Wiki\AnimeSchema;
use App\Http\Api\Schema\Wiki\GroupSchema;
use App\Http\Api\Schema\Wiki\ImageSchema;
use App\Http\Api\Schema\Wiki\SongSchema;
use App\Http\Api\Schema\Wiki\VideoSchema;
use App\Http\Resources\List\Resource\ExternalProfileResource;
use App\Models\List\ExternalProfile;

Expand Down Expand Up @@ -45,6 +49,11 @@ public function allowedIncludes(): array
new AllowedInclude(new AnimeSchema(), ExternalProfile::RELATION_ANIMES),
new AllowedInclude(new ExternalEntrySchema(), ExternalProfile::RELATION_EXTERNAL_ENTRIES),
new AllowedInclude(new UserSchema(), ExternalProfile::RELATION_USER),

new AllowedInclude(new GroupSchema(), "externalentries.anime.animethemes.group"),
new AllowedInclude(new VideoSchema(), "externalentries.anime.animethemes.animethemeentries.videos"),
new AllowedInclude(new SongSchema(), "externalentries.anime.animethemes.song"),
new AllowedInclude(new ImageSchema(), "externalentries.anime.images"),
];
}

Expand All @@ -58,12 +67,12 @@ public function fields(): array
return array_merge(
parent::fields(),
[
new ExternalProfileIdField($this),
new IdField($this, ExternalProfile::ATTRIBUTE_ID),
new ExternalProfileNameField($this),
new ExternalProfileSiteField($this),
new ExternalProfileVisibilityField($this),
new ExternalProfileUserIdField($this),
],
);
}
}
}
6 changes: 6 additions & 0 deletions app/Http/Controllers/Api/List/ExternalProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use App\Http\Resources\List\Resource\ExternalProfileResource;
use App\Models\List\ExternalProfile;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Laravel\Pennant\Middleware\EnsureFeaturesAreActive;

Expand Down Expand Up @@ -63,6 +64,11 @@ public function index(IndexRequest $request, IndexAction $action): ExternalProfi

$builder = ExternalProfile::query()->where(ExternalProfile::ATTRIBUTE_VISIBILITY, ExternalProfileVisibility::PUBLIC->value);

$userId = Auth::id();
if ($userId) {
$builder->orWhere(ExternalProfile::ATTRIBUTE_USER, Auth::id());
}

$externalprofiles = $query->hasSearchCriteria()
? $action->search($query, $request->schema())
: $action->index($builder, $query, $request->schema());
Expand Down
95 changes: 95 additions & 0 deletions app/Http/Controllers/List/External/ExternalTokenAuthController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\List\External;

use App\Enums\Models\List\ExternalProfileSite;
use App\Features\AllowExternalProfileManagement;
use App\Http\Controllers\Controller;
use App\Http\Middleware\Api\EnabledOnlyOnLocalhost;
use App\Models\List\ExternalProfile;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Str;
use Laravel\Pennant\Middleware\EnsureFeaturesAreActive;

/**
* Class ExternalTokenAuthController.
*/
class ExternalTokenAuthController extends Controller
{
/**
* Create a new controller instance.
*/
public function __construct()
{
$isExternalProfileManagementAllowed = Str::of(EnsureFeaturesAreActive::class)
->append(':')
->append(AllowExternalProfileManagement::class)
->__toString();

$this->middleware(EnabledOnlyOnLocalhost::class);
$this->middleware($isExternalProfileManagementAllowed);
}

/**
* This will redirect the user to the appropriate auth service.
*
* @param Request $request
* @return RedirectResponse|JsonResponse
*/
public function index(Request $request): RedirectResponse|JsonResponse
{
$validated = array_merge(
$request->all(),
[ExternalProfile::ATTRIBUTE_USER => Auth::id()]
);

$site = Arr::get($validated, ExternalProfile::ATTRIBUTE_SITE);
$profileSite = ExternalProfileSite::fromLocalizedName($site);

if ($profileSite instanceof ExternalProfileSite) {
$link = $this->getRedirectLink($profileSite);

if ($link !== null) {
return Redirect::to($link);
}
}

return new JsonResponse([
'error' => 'invalid site',
], 400);
}

/**
* Get the link of the external site to authenticate the user.
*
* @param ExternalProfileSite $site
* @return string
*/
private function getRedirectLink(ExternalProfileSite $site): ?string
{
switch ($site) {
case ExternalProfileSite::KITSU:
return null;
case ExternalProfileSite::MAL:
return null;
case ExternalProfileSite::ANILIST:
$query = [
'client_id' => Config::get('services.anilist.client_id'),
'redirect_uri' => Config::get('services.anilist.redirect_uri'),
'response_type' => 'code',
];

return 'https://anilist.co/api/v2/oauth/authorize?' . http_build_query($query);
default:
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@

declare(strict_types=1);

namespace App\Http\Controllers\Api\List\External;
namespace App\Http\Controllers\List\External;

use App\Actions\Models\List\ExternalTokenCallbackAction;
use App\Features\AllowExternalProfileManagement;
use App\Http\Api\Schema\List\ExternalProfileSchema;
use App\Http\Api\Schema\Schema;
use App\Http\Controllers\Api\BaseController;
use App\Http\Requests\Api\IndexRequest;
use App\Models\List\External\ExternalToken;
use App\Http\Controllers\Controller;
use App\Http\Middleware\Api\EnabledOnlyOnLocalhost;
use App\Models\List\ExternalProfile;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redirect;
Expand All @@ -23,30 +21,29 @@
/**
* Class ExternalTokenCallbackController.
*/
class ExternalTokenCallbackController extends BaseController
class ExternalTokenCallbackController extends Controller
{
/**
* Create a new controller instance.
*/
public function __construct()
{
parent::__construct(ExternalToken::class, 'externaltoken');

$isExternalProfileManagementAllowed = Str::of(EnsureFeaturesAreActive::class)
->append(':')
->append(AllowExternalProfileManagement::class)
->__toString();

$this->middleware(EnabledOnlyOnLocalhost::class);
$this->middleware($isExternalProfileManagementAllowed);
}

/**
* This is the redirect URL which is set in the external provider.
*
* @param IndexRequest $request
* @param Request $request
* @return RedirectResponse|JsonResponse
*/
public function index(IndexRequest $request): RedirectResponse|JsonResponse
public function index(Request $request): RedirectResponse|JsonResponse
{
$validated = array_merge(
$request->all(),
Expand All @@ -71,16 +68,4 @@ public function index(IndexRequest $request): RedirectResponse|JsonResponse

return Redirect::to($clientUrl);
}

/**
* Get the underlying schema.
*
* @return Schema
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function schema(): Schema
{
return new ExternalProfileSchema();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

declare(strict_types=1);

namespace App\Http\Controllers\Api\List;
namespace App\Http\Controllers\List;

use App\Features\AllowExternalProfileManagement;
use App\Http\Controllers\Api\BaseController;
use App\Http\Controllers\Controller;
use App\Http\Middleware\Api\EnabledOnlyOnLocalhost;
use App\Http\Requests\Api\ShowRequest;
use App\Models\List\ExternalProfile;
Expand All @@ -15,15 +15,13 @@
/**
* Class SyncExternalProfileController.
*/
class SyncExternalProfileController extends BaseController
class SyncExternalProfileController extends Controller
{
/**
* Create a new controller instance.
*/
public function __construct()
{
parent::__construct(ExternalProfile::class, 'externalprofile');

$isExternalProfileManagementAllowed = Str::of(EnsureFeaturesAreActive::class)
->append(':')
->append(AllowExternalProfileManagement::class)
Expand Down
12 changes: 10 additions & 2 deletions app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace App\Providers;

use App\Constants\Config\ApiConstants;
use App\Constants\Config\AudioConstants;
use App\Constants\Config\DumpConstants;
use App\Constants\Config\VideoConstants;
use App\Enums\Auth\SpecialPermission;
use App\Http\Middleware\Auth\Authenticate;
use App\Models\Auth\User;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
Expand Down Expand Up @@ -75,9 +77,15 @@ public function boot(): void
->prefix(Config::get(VideoConstants::SCRIPT_PATH_QUALIFIED))
->group(base_path('routes/script.php'));

Route::middleware(['web', Authenticate::class, 'throttle:api'])
->domain(Config::get(ApiConstants::URL_QUALIFIED))
->prefix(Config::get(ApiConstants::PATH_QUALIFIED))
->as('api.')
->group(base_path('routes/externallist.php'));

Route::middleware('api')
->domain(Config::get('api.url'))
->prefix(Config::get('api.path'))
->domain(Config::get(ApiConstants::URL_QUALIFIED))
->prefix(Config::get(ApiConstants::PATH_QUALIFIED))
->as('api.')
->group(base_path('routes/api.php'));
});
Expand Down
Loading

0 comments on commit eeff29b

Please sign in to comment.