mirror of
https://github.com/koel/koel
synced 2025-02-17 13:58:28 +00:00
fix: assing default user to S3-imported songs
This commit is contained in:
parent
854900b9b7
commit
179faefeed
7 changed files with 51 additions and 21 deletions
|
@ -3,7 +3,7 @@
|
|||
namespace App\Console\Commands\Admin;
|
||||
|
||||
use App\Console\Commands\Traits\AskForPassword;
|
||||
use App\Models\User;
|
||||
use App\Repositories\UserRepository;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Hashing\Hasher as Hash;
|
||||
|
||||
|
@ -15,7 +15,7 @@ class ChangePasswordCommand extends Command
|
|||
{email? : The user's email. If empty, will get the default admin user.}";
|
||||
protected $description = "Change a user's password";
|
||||
|
||||
public function __construct(private Hash $hash)
|
||||
public function __construct(private Hash $hash, private UserRepository $userRepository)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
@ -24,10 +24,9 @@ class ChangePasswordCommand extends Command
|
|||
{
|
||||
$email = $this->argument('email');
|
||||
|
||||
/** @var User|null $user */
|
||||
$user = $email
|
||||
? User::query()->where('email', $email)->first()
|
||||
: User::query()->where('is_admin', true)->first();
|
||||
? $this->userRepository->findOneByEmail($email)
|
||||
: $this->userRepository->getDefaultAdminUser();
|
||||
|
||||
if (!$user) {
|
||||
$this->error('The user account cannot be found.');
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Console\Commands;
|
|||
use App\Libraries\WatchRecord\InotifyWatchRecord;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Services\MediaScanner;
|
||||
use App\Values\ScanConfiguration;
|
||||
use App\Values\ScanResult;
|
||||
|
@ -29,7 +30,7 @@ class ScanCommand extends Command
|
|||
private ?string $mediaPath;
|
||||
private ProgressBar $progressBar;
|
||||
|
||||
public function __construct(private MediaScanner $mediaScanner)
|
||||
public function __construct(private MediaScanner $mediaScanner, private UserRepository $userRepository)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
|
@ -170,8 +171,8 @@ class ScanCommand extends Command
|
|||
return $user;
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::where('is_admin', true)->oldest()->firstOrFail();
|
||||
$user = $this->userRepository->getDefaultAdminUser();
|
||||
|
||||
$this->components->warn(
|
||||
"No song owner specified. Setting the first admin ($user->name, ID $user->id) as owner."
|
||||
);
|
||||
|
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserRepository extends Repository
|
||||
{
|
||||
public function getDefaultAdminUser(): User
|
||||
{
|
||||
return User::query()->where('is_admin', true)->oldest()->firstOrFail();
|
||||
}
|
||||
|
||||
public function findOneByEmail(string $email): ?User
|
||||
{
|
||||
return User::query()->where('email', $email)->first();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,6 @@ use SplFileInfo;
|
|||
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* Get a unique hash from a file path.
|
||||
* This hash can then be used as the Song record's ID.
|
||||
*/
|
||||
public static function getFileHash(string $path): string
|
||||
{
|
||||
return md5(config('app.key') . $path);
|
||||
}
|
||||
|
||||
public static function getModifiedTime(string|SplFileInfo $file): int
|
||||
{
|
||||
$file = is_string($file) ? new SplFileInfo($file) : $file;
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Models\Album;
|
|||
use App\Models\Artist;
|
||||
use App\Models\Song;
|
||||
use App\Repositories\SongRepository;
|
||||
use App\Repositories\UserRepository;
|
||||
use Aws\S3\S3ClientInterface;
|
||||
use Illuminate\Cache\Repository as Cache;
|
||||
|
||||
|
@ -18,6 +19,7 @@ class S3Service implements ObjectStorageInterface
|
|||
private Cache $cache,
|
||||
private MediaMetadataService $mediaMetadataService,
|
||||
private SongRepository $songRepository,
|
||||
private UserRepository $userRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -48,6 +50,7 @@ class S3Service implements ObjectStorageInterface
|
|||
int $track,
|
||||
string $lyrics
|
||||
): Song {
|
||||
$user = $this->userRepository->getDefaultAdminUser();
|
||||
$path = Song::getPathFromS3BucketAndKey($bucket, $key);
|
||||
$artist = Artist::getOrCreate($artistName);
|
||||
|
||||
|
@ -74,6 +77,8 @@ class S3Service implements ObjectStorageInterface
|
|||
'track' => $track,
|
||||
'lyrics' => $lyrics,
|
||||
'mtime' => time(),
|
||||
'owner_id' => $user->id,
|
||||
'is_public' => true,
|
||||
]);
|
||||
|
||||
event(new LibraryChanged());
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Services;
|
|||
use App\Exceptions\InvitationNotFoundException;
|
||||
use App\Mail\UserInvite;
|
||||
use App\Models\User;
|
||||
use App\Repositories\UserRepository;
|
||||
use Illuminate\Contracts\Hashing\Hasher as Hash;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
@ -13,7 +14,7 @@ use Illuminate\Support\Str;
|
|||
|
||||
class UserInvitationService
|
||||
{
|
||||
public function __construct(private Hash $hash)
|
||||
public function __construct(private Hash $hash, private UserRepository $userRepository)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -36,8 +37,7 @@ class UserInvitationService
|
|||
/** @throws InvitationNotFoundException */
|
||||
public function revokeByEmail(string $email): void
|
||||
{
|
||||
/** @var ?User $user */
|
||||
$user = User::query()->where('email', $email)->first();
|
||||
$user = $this->userRepository->findOneByEmail($email);
|
||||
throw_unless($user?->is_prospect, new InvitationNotFoundException());
|
||||
$user->delete();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Tests\Unit\Services;
|
|||
use App\Events\LibraryChanged;
|
||||
use App\Models\Song;
|
||||
use App\Repositories\SongRepository;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Services\MediaMetadataService;
|
||||
use App\Services\S3Service;
|
||||
use Aws\CommandInterface;
|
||||
|
@ -16,11 +17,14 @@ use Mockery\LegacyMockInterface;
|
|||
use Mockery\MockInterface;
|
||||
use Tests\TestCase;
|
||||
|
||||
use function Tests\create_admin;
|
||||
|
||||
class S3ServiceTest extends TestCase
|
||||
{
|
||||
private S3ClientInterface|LegacyMockInterface|MockInterface $s3Client;
|
||||
private Cache|LegacyMockInterface|MockInterface $cache;
|
||||
private SongRepository|LegacyMockInterface|MockInterface $songRepository;
|
||||
private UserRepository|LegacyMockInterface|MockInterface $userRepository;
|
||||
private S3Service $s3Service;
|
||||
|
||||
public function setUp(): void
|
||||
|
@ -32,14 +36,26 @@ class S3ServiceTest extends TestCase
|
|||
|
||||
$metadataService = Mockery::mock(MediaMetadataService::class);
|
||||
$this->songRepository = Mockery::mock(SongRepository::class);
|
||||
$this->userRepository = Mockery::mock(UserRepository::class);
|
||||
|
||||
$this->s3Service = new S3Service($this->s3Client, $this->cache, $metadataService, $this->songRepository);
|
||||
$this->s3Service = new S3Service(
|
||||
$this->s3Client,
|
||||
$this->cache,
|
||||
$metadataService,
|
||||
$this->songRepository,
|
||||
$this->userRepository
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreateSongEntry(): void
|
||||
{
|
||||
$this->expectsEvents(LibraryChanged::class);
|
||||
|
||||
$user = create_admin();
|
||||
$this->userRepository->shouldReceive('getDefaultAdminUser')
|
||||
->once()
|
||||
->andReturn($user);
|
||||
|
||||
$song = $this->s3Service->createSongEntry(
|
||||
bucket: 'foo',
|
||||
key: 'bar',
|
||||
|
@ -60,12 +76,18 @@ class S3ServiceTest extends TestCase
|
|||
self::assertSame(355.5, $song->length);
|
||||
self::assertSame('Is this the real life?', $song->lyrics);
|
||||
self::assertSame(1, $song->track);
|
||||
self::assertSame($user->id, $song->owner_id);
|
||||
}
|
||||
|
||||
public function testUpdateSongEntry(): void
|
||||
{
|
||||
$this->expectsEvents(LibraryChanged::class);
|
||||
|
||||
$user = create_admin();
|
||||
$this->userRepository->shouldReceive('getDefaultAdminUser')
|
||||
->once()
|
||||
->andReturn($user);
|
||||
|
||||
/** @var Song $song */
|
||||
$song = Song::factory()->create([
|
||||
'path' => 's3://foo/bar',
|
||||
|
@ -95,6 +117,7 @@ class S3ServiceTest extends TestCase
|
|||
self::assertSame(355.5, $song->length);
|
||||
self::assertSame('Is this the real life?', $song->lyrics);
|
||||
self::assertSame(1, $song->track);
|
||||
self::assertSame($user->id, $song->owner_id);
|
||||
}
|
||||
|
||||
public function testDeleteSong(): void
|
||||
|
|
Loading…
Add table
Reference in a new issue