diff --git a/app/Http/Middleware/LoginRequired.php b/app/Http/Middleware/LoginRequired.php index d381459aa75..83a72f7b51c 100644 --- a/app/Http/Middleware/LoginRequired.php +++ b/app/Http/Middleware/LoginRequired.php @@ -6,6 +6,7 @@ use App\Exceptions\ConfigurationException; use App\Exceptions\ConfigurationKeyMissingException; use App\Exceptions\Internal\FrameworkException; +use App\Exceptions\Internal\LycheeLogicException; use App\Models\Configs; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -19,32 +20,45 @@ */ class LoginRequired { + public const ROOT = 'root'; + public const ALBUM = 'album'; + /** * Handle an incoming request. * - * @param Request $request - * @param \Closure $next - * - * @return mixed + * @param Request $request the incoming request to serve + * @param \Closure $next the next operation to be applied to the + * request + * @param string $requiredStatus the required login status; either + * {@link self::ROOT} or + * {@link self::ALBUM} * * @throws ConfigurationException * @throws FrameworkException */ - public function handle(Request $request, \Closure $next): mixed + public function handle(Request $request, \Closure $next, string $requiredStatus): mixed { + // We are logged in. Proceed. + if (Auth::user() !== null) { + return $next($request); + } + $dir_url = config('app.dir_url'); if (Features::inactive('livewire') && !Str::startsWith($request->getRequestUri(), $dir_url . '/livewire/')) { return $next($request); } + if ($requiredStatus !== self::ALBUM && $requiredStatus !== self::ROOT) { + throw new LycheeLogicException($requiredStatus . ' is not a valid login requirement.'); + } + try { if (!Configs::getValueAsBool('login_required')) { // Login is not required. Proceed. return $next($request); } - if (Auth::user() !== null) { - // We are logged in. Proceed. + if ($requiredStatus === self::ALBUM && Configs::getValueAsBool('login_required_root_only')) { return $next($request); } diff --git a/database/migrations/2024_06_23_201042_enforce_login_on_gallery_only.php b/database/migrations/2024_06_23_201042_enforce_login_on_gallery_only.php new file mode 100644 index 00000000000..b6fa3235230 --- /dev/null +++ b/database/migrations/2024_06_23_201042_enforce_login_on_gallery_only.php @@ -0,0 +1,21 @@ + 'login_required_root_only', + 'value' => '1', + 'is_secret' => false, + 'cat' => self::GALLERY, + 'type_range' => self::BOOL, + 'description' => 'Require user to login only on root. A user with a direct link to an album can still access it.', + ], + ]; + } +}; diff --git a/routes/api.php b/routes/api.php index 4683c5882fa..b450f2927a1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -19,14 +19,14 @@ /** * ALBUMS. */ -Route::post('/Albums::get', [AlbumsController::class, 'get'])->middleware(['login_required']); -Route::post('/Albums::getPositionData', [AlbumsController::class, 'getPositionData'])->middleware(['login_required']); -Route::post('/Albums::tree', [AlbumsController::class, 'tree'])->middleware(['login_required']); +Route::post('/Albums::get', [AlbumsController::class, 'get'])->middleware(['login_required:root']); +Route::post('/Albums::getPositionData', [AlbumsController::class, 'getPositionData'])->middleware(['login_required:root']); +Route::post('/Albums::tree', [AlbumsController::class, 'tree'])->middleware(['login_required:root']); /** * ALBUM. */ -Route::post('/Album::get', [AlbumController::class, 'get'])->middleware(['login_required']); +Route::post('/Album::get', [AlbumController::class, 'get'])->middleware(['login_required:album']); Route::post('/Album::getPositionData', [AlbumController::class, 'getPositionData']); Route::post('/Album::unlock', [AlbumController::class, 'unlock']); Route::post('/Album::add', [AlbumController::class, 'add']); @@ -68,8 +68,8 @@ /** * PHOTO. */ -Route::post('/Photo::get', [PhotoController::class, 'get'])->middleware(['login_required']); -Route::post('/Photo::getRandom', [PhotoController::class, 'getRandom'])->middleware(['login_required']); +Route::post('/Photo::get', [PhotoController::class, 'get'])->middleware(['login_required:album']); +Route::post('/Photo::getRandom', [PhotoController::class, 'getRandom']); Route::post('/Photo::setTitle', [PhotoController::class, 'setTitle']); Route::post('/Photo::setDescription', [PhotoController::class, 'setDescription']); Route::post('/Photo::setStar', [PhotoController::class, 'setStar']); diff --git a/routes/web-livewire.php b/routes/web-livewire.php index a565c09a0e2..6ba20284623 100644 --- a/routes/web-livewire.php +++ b/routes/web-livewire.php @@ -43,7 +43,7 @@ Route::get('/jobs', Jobs::class)->name('jobs'); Route::get('/maintenance', Maintenance::class)->name('maintenance'); - Route::middleware(['login_required']) + Route::middleware(['login_required:album']) ->group(function () { Route::get('/map/{albumId?}', Map::class)->name('livewire-map'); Route::get('/frame/{albumId?}', Frame::class)->name('livewire-frame'); @@ -58,7 +58,7 @@ Route::prefix(Features::when('livewire', '', 'livewire')) ->group(function () { Route::get('/landing', Landing::class)->name('landing'); - Route::get('/gallery', Albums::class)->middleware(['login_required'])->name('livewire-gallery'); + Route::get('/gallery', Albums::class)->middleware(['login_required:root'])->name('livewire-gallery'); Route::get('/', [RedirectController::class, 'view'])->name('livewire-index'); }); });