From a8c78adf65e7b48436fedc0a722b65efae609313 Mon Sep 17 00:00:00 2001 From: Phan An Date: Sat, 6 Jan 2024 12:31:50 +0100 Subject: [PATCH] feat: make song edit/deletion plus-aware --- app/Helpers.php | 7 +++++ .../Controllers/API/SettingController.php | 3 +- app/Http/Controllers/API/SongController.php | 4 --- app/Http/Requests/API/DeleteSongsRequest.php | 15 ++++++++++ app/Http/Requests/API/SongUpdateRequest.php | 17 ++++++++++- app/Services/CommunityLicenseService.php | 7 +++++ app/Services/FileScanner.php | 4 +-- .../js/components/song/SongContextMenu.vue | 13 ++++++-- tests/Feature/SettingTest.php | 2 +- tests/Feature/UploadTest.php | 2 +- .../Integration/Models/SongZipArchiveTest.php | 6 ++-- .../ApplicationInformationServiceTest.php | 2 +- .../Integration/Services/FileScannerTest.php | 30 +++++++++---------- .../Services/MediaMetadataServiceTest.php | 2 +- .../Integration/Services/MediaScannerTest.php | 2 +- .../Services/UploadServiceTest.php | 2 +- tests/Traits/CreatesApplication.php | 6 ++-- tests/Unit/Listeners/WriteSyncLogTest.php | 4 +-- tests/Unit/Models/ArtistTest.php | 2 +- .../Services/ApiClients/LastfmClientTest.php | 4 +-- tests/Unit/Services/LastfmServiceTest.php | 8 ++--- tests/Unit/Services/SimpleLrcReaderTest.php | 2 +- tests/Unit/Services/SpotifyServiceTest.php | 2 +- tests/Unit/Services/YouTubeServiceTest.php | 2 +- 24 files changed, 97 insertions(+), 51 deletions(-) diff --git a/app/Helpers.php b/app/Helpers.php index 025a14b9..84d57a4d 100644 --- a/app/Helpers.php +++ b/app/Helpers.php @@ -71,3 +71,10 @@ function attempt_unless($condition, callable $callback, bool $log = true): mixed { return !value($condition) ? attempt($callback, $log) : null; } + +if (!function_exists('test_path')) { + function test_path(string $path = ''): string + { + return base_path('tests' . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR)); + } +} diff --git a/app/Http/Controllers/API/SettingController.php b/app/Http/Controllers/API/SettingController.php index e881a0a0..3f020de0 100644 --- a/app/Http/Controllers/API/SettingController.php +++ b/app/Http/Controllers/API/SettingController.php @@ -7,6 +7,7 @@ use App\Http\Requests\API\SettingRequest; use App\Models\Setting; use App\Models\User; use App\Services\MediaScanner; +use App\Values\ScanConfiguration; use Illuminate\Contracts\Auth\Authenticatable; class SettingController extends Controller @@ -22,7 +23,7 @@ class SettingController extends Controller Setting::set('media_path', rtrim(trim($request->media_path), '/')); - $this->mediaSyncService->scan($this->user, makePublic: true); + $this->mediaSyncService->scan(ScanConfiguration::make(owner: $this->user, makePublic: true)); return response()->noContent(); } diff --git a/app/Http/Controllers/API/SongController.php b/app/Http/Controllers/API/SongController.php index 458b547f..32123118 100644 --- a/app/Http/Controllers/API/SongController.php +++ b/app/Http/Controllers/API/SongController.php @@ -50,8 +50,6 @@ class SongController extends Controller public function update(SongUpdateRequest $request) { - $this->authorize('admin', $this->user); - $updatedSongs = $this->songService->updateSongs($request->songs, SongUpdateData::fromRequest($request)); $albums = $this->albumRepository->getMany($updatedSongs->pluck('album_id')->toArray()); @@ -72,8 +70,6 @@ class SongController extends Controller public function destroy(DeleteSongsRequest $request) { - $this->authorize('admin', $this->user); - $this->songService->deleteSongs($request->songs); return response()->noContent(); diff --git a/app/Http/Requests/API/DeleteSongsRequest.php b/app/Http/Requests/API/DeleteSongsRequest.php index 46ff7e34..5436792e 100644 --- a/app/Http/Requests/API/DeleteSongsRequest.php +++ b/app/Http/Requests/API/DeleteSongsRequest.php @@ -2,6 +2,9 @@ namespace App\Http\Requests\API; +use App\Facades\License; +use App\Models\Song; + /** @property-read array $songs */ class DeleteSongsRequest extends Request { @@ -12,4 +15,16 @@ class DeleteSongsRequest extends Request 'songs' => 'required|array|exists:songs,id', ]; } + + public function authorize(): bool + { + if (License::isCommunity()) { + return $this->user()->is_admin; + } + + return Song::query() + ->whereIn('id', $this->songs) + ->get() + ->every(fn (Song $song): bool => $song->owner_id === $this->user()->id); + } } diff --git a/app/Http/Requests/API/SongUpdateRequest.php b/app/Http/Requests/API/SongUpdateRequest.php index 051c4347..e73e5b4f 100644 --- a/app/Http/Requests/API/SongUpdateRequest.php +++ b/app/Http/Requests/API/SongUpdateRequest.php @@ -2,6 +2,9 @@ namespace App\Http\Requests\API; +use App\Facades\License; +use App\Models\Song; + /** * @property array $songs * @property array $data @@ -13,7 +16,19 @@ class SongUpdateRequest extends Request { return [ 'data' => 'required|array', - 'songs' => 'required|array', + 'songs' => 'required|array|exists:songs,id', ]; } + + public function authorize(): bool + { + if (License::isCommunity()) { + return $this->user()->is_admin; + } + + return Song::query() + ->whereIn('id', $this->songs) + ->get() + ->every(fn (Song $song): bool => $song->owner_id === $this->user()->id); + } } diff --git a/app/Services/CommunityLicenseService.php b/app/Services/CommunityLicenseService.php index 13dcdabc..795a1b57 100644 --- a/app/Services/CommunityLicenseService.php +++ b/app/Services/CommunityLicenseService.php @@ -2,8 +2,15 @@ namespace App\Services; +use App\Services\ApiClients\LemonSqueezyApiClient; + class CommunityLicenseService extends LicenseService { + public function __construct(LemonSqueezyApiClient $client) + { + parent::__construct($client, config('app.key')); + } + public function isPlus(): bool { return false; diff --git a/app/Services/FileScanner.php b/app/Services/FileScanner.php index 9b864a87..5ab3ed62 100644 --- a/app/Services/FileScanner.php +++ b/app/Services/FileScanner.php @@ -48,7 +48,7 @@ class FileScanner return $this; } - public function getFileScanInformation(): ?SongScanInformation + public function getScanInformation(): ?SongScanInformation { $raw = $this->getID3->analyze($this->filePath); $this->syncError = Arr::get($raw, 'error.0') ?: (Arr::get($raw, 'playtime_seconds') ? null : 'Empty file'); @@ -71,7 +71,7 @@ class FileScanner return ScanResult::skipped($this->filePath); } - $info = $this->getFileScanInformation()?->toArray(); + $info = $this->getScanInformation()?->toArray(); if (!$info) { return ScanResult::error($this->filePath, $this->syncError); diff --git a/resources/assets/js/components/song/SongContextMenu.vue b/resources/assets/js/components/song/SongContextMenu.vue index 48dbf029..b2402b74 100644 --- a/resources/assets/js/components/song/SongContextMenu.vue +++ b/resources/assets/js/components/song/SongContextMenu.vue @@ -42,7 +42,7 @@
  • -
  • Edit…
  • +
  • Edit…
  • Download
  • Copy Shareable URL
  • @@ -51,7 +51,7 @@
  • Remove from Playlist
  • -