Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove requirement of Auth in photo upload, pass ownerId as argument #1787

Merged
merged 1 commit into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/Actions/Import/Exec.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class Exec
* @param bool $enableCLIFormatting determines whether the output shall be formatted for CLI or as JSON
* @param int $memLimit the threshold when a memory warning shall be reported; `0` means unlimited
*/
public function __construct(ImportMode $importMode, bool $enableCLIFormatting, int $memLimit = 0)
public function __construct(ImportMode $importMode, int $intendedOwnerId, bool $enableCLIFormatting, int $memLimit = 0)
{
Session::forget('cancel');
$this->importMode = $importMode;
$this->photoCreate = new PhotoCreate($importMode);
$this->photoCreate = new PhotoCreate($importMode, $intendedOwnerId);
$this->albumCreate = new AlbumCreate();
$this->enableCLIFormatting = $enableCLIFormatting;
$this->memLimit = $memLimit;
Expand Down
11 changes: 6 additions & 5 deletions app/Actions/Import/FromServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
class FromServer
{
/**
* @param string[] $paths the server path to import from
* @param Album|null $album the album to import into
* @param ImportMode $importMode the import mode
* @param string[] $paths the server path to import from
* @param Album|null $album the album to import into
* @param ImportMode $importMode the import mode
* @param int $intendedOwnerId the intended owner of those pictures
*
* @return StreamedResponse
*/
public function do(array $paths, ?Album $album, ImportMode $importMode): StreamedResponse
public function do(array $paths, ?Album $album, ImportMode $importMode, int $intendedOwnerId): StreamedResponse
{
$exec = new Exec($importMode, false, $this->determineMemLimit());
$exec = new Exec($importMode, $intendedOwnerId, false, $this->determineMemLimit());

$response = new StreamedResponse();
$response->headers->set('Content-Type', 'application/json');
Expand Down
11 changes: 6 additions & 5 deletions app/Actions/Import/FromUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,20 @@ class FromUrl
*
* @param string[] $urls
* @param Album|null $album
* @param int $intendedOwnerId
*
* @return Collection<Photo> the collection of imported photos
*
* @throws MassImportException
*/
public function do(array $urls, ?Album $album): Collection
public function do(array $urls, ?Album $album, int $intendedOwnerId): Collection
{
$result = new Collection();
$exceptions = [];
$create = new Create(new ImportMode(
true,
Configs::getValueAsBool('skip_duplicates')
));
$create = new Create(
new ImportMode(deleteImported: true, skipDuplicates: Configs::getValueAsBool('skip_duplicates')),
$intendedOwnerId
);

foreach ($urls as $url) {
try {
Expand Down
4 changes: 2 additions & 2 deletions app/Actions/Photo/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class Create
/** @var AddStrategyParameters the strategy parameters prepared and compiled by this class */
protected AddStrategyParameters $strategyParameters;

public function __construct(?ImportMode $importMode)
public function __construct(?ImportMode $importMode, int $intendedOwnerId)
{
$this->strategyParameters = new AddStrategyParameters($importMode);
$this->strategyParameters = new AddStrategyParameters($importMode, $intendedOwnerId);
}

/**
Expand Down
16 changes: 5 additions & 11 deletions app/Actions/Photo/Strategies/AbstractAddStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
use App\Exceptions\ModelDBException;
use App\Exceptions\UnauthenticatedException;
use App\Models\Photo;
use Illuminate\Support\Facades\Auth;

abstract class AbstractAddStrategy
{
protected AddStrategyParameters $parameters;
protected Photo $photo;

protected function __construct(AddStrategyParameters $parameters, Photo $photo)
{
$this->parameters = $parameters;
$this->photo = $photo;
protected function __construct(
protected AddStrategyParameters $parameters,
protected Photo $photo
) {
}

/**
Expand Down Expand Up @@ -116,9 +112,7 @@ protected function setParentAndOwnership(): void
// Avoid unnecessary DB request, when we access the album of a
// photo later (e.g. when a notification is sent).
$this->photo->setRelation('album', null);
/** @var int */
$userId = Auth::id() ?? throw new UnauthenticatedException();
$this->photo->owner_id = $userId;
$this->photo->owner_id = $this->parameters->intendedOwnerId;
}
}
}
5 changes: 4 additions & 1 deletion app/Actions/Photo/Strategies/AddPhotoPartnerStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public function do(): Photo
// "steals away" the stored video file from the existing video entity
// and moves it to the correct destination of a live partner for the
// photo.
$parameters = new AddStrategyParameters(new ImportMode(true));
$parameters = new AddStrategyParameters(
new ImportMode(deleteImported: true),
$this->parameters->intendedOwnerId
);
$videoStrategy = new AddVideoPartnerStrategy(
$parameters,
$this->existingVideo->size_variants->getOriginal()->getFile(),
Expand Down
6 changes: 5 additions & 1 deletion app/Actions/Photo/Strategies/AddStrategyParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class AddStrategyParameters
{
public ImportMode $importMode;

/** @var int Indicates the intended owner of the image. */
public int $intendedOwnerId;

/** @var Album|null the intended parent album */
public ?Album $album = null;

Expand All @@ -21,8 +24,9 @@ class AddStrategyParameters
/** @var Extractor|null the extracted EXIF information */
public ?Extractor $exifInfo = null;

public function __construct(ImportMode $importMode)
public function __construct(ImportMode $importMode, int $intendedOwnerId)
{
$this->importMode = $importMode;
$this->intendedOwnerId = $intendedOwnerId;
}
}
28 changes: 4 additions & 24 deletions app/Actions/Photo/Strategies/ImportMode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,12 @@

class ImportMode
{
protected bool $deleteImported = false;
protected bool $skipDuplicates = false;
protected bool $importViaSymlink = false;
protected bool $resyncMetadata = false;

public function __construct(
bool $deleteImported = false,
bool $skipDuplicates = false,
bool $importViaSymlink = false,
bool $resyncMetadata = false
protected readonly bool $deleteImported = false,
protected readonly bool $skipDuplicates = false,
protected bool $importViaSymlink = false,
protected bool $resyncMetadata = false
) {
$this->setMode(
$deleteImported, $skipDuplicates, $importViaSymlink, $resyncMetadata
);
}

public function setMode(
bool $deleteImported = false,
bool $skipDuplicates = false,
bool $importViaSymlink = false,
bool $resyncMetadata = false
): void {
$this->deleteImported = $deleteImported;
$this->skipDuplicates = $skipDuplicates;
$this->importViaSymlink = $importViaSymlink;
$this->resyncMetadata = $resyncMetadata;
// avoid incompatible settings (delete originals takes precedence over symbolic links)
if ($deleteImported) {
$this->importViaSymlink = false;
Expand Down
4 changes: 1 addition & 3 deletions app/Console/Commands/Sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use App\Models\Configs;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\Console\Exception\ExceptionInterface as SymfonyConsoleException;

class Sync extends Command
Expand Down Expand Up @@ -105,12 +104,11 @@ public function handle(): int
$importViaSymlink,
$resyncMetadata
),
$owner_id,
true,
0
);

Auth::loginUsingId($owner_id);

$this->info('Start syncing.');

foreach ($directories as $directory) {
Expand Down
12 changes: 10 additions & 2 deletions app/Http/Controllers/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Actions\Import\FromServer;
use App\Actions\Import\FromUrl;
use App\Exceptions\MassImportException;
use App\Exceptions\UnauthenticatedException;
use App\Http\Requests\Import\CancelImportServerRequest;
use App\Http\Requests\Import\ImportFromUrlRequest;
use App\Http\Requests\Import\ImportServerRequest;
Expand All @@ -13,6 +14,7 @@
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Routing\Controller;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Symfony\Component\HttpFoundation\StreamedResponse;

Expand Down Expand Up @@ -58,7 +60,10 @@ class ImportController extends Controller
*/
public function url(ImportFromUrlRequest $request, FromUrl $fromUrl): AnonymousResourceCollection
{
$photos = $fromUrl->do($request->urls(), $request->album());
/** @var int $currentUserId */
$currentUserId = Auth::id() ?? throw new UnauthenticatedException();

$photos = $fromUrl->do($request->urls(), $request->album(), $currentUserId);

return PhotoResource::collection($photos);
}
Expand All @@ -71,8 +76,11 @@ public function url(ImportFromUrlRequest $request, FromUrl $fromUrl): AnonymousR
*/
public function server(ImportServerRequest $request, FromServer $fromServer): StreamedResponse
{
/** @var int $currentUserId */
$currentUserId = Auth::id() ?? throw new UnauthenticatedException();

return $fromServer->do(
$request->paths(), $request->album(), $request->importMode()
$request->paths(), $request->album(), $request->importMode(), $currentUserId
);
}

Expand Down
13 changes: 9 additions & 4 deletions app/Http/Controllers/PhotoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Contracts\Exceptions\LycheeException;
use App\Exceptions\MediaFileOperationException;
use App\Exceptions\ModelDBException;
use App\Exceptions\UnauthenticatedException;
use App\Http\Requests\Photo\AddPhotoRequest;
use App\Http\Requests\Photo\ArchivePhotosRequest;
use App\Http\Requests\Photo\ClearSymLinkRequest;
Expand All @@ -37,6 +38,7 @@
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class PhotoController extends Controller
Expand Down Expand Up @@ -98,6 +100,9 @@ public function getRandom(): PhotoResource
*/
public function add(AddPhotoRequest $request): PhotoResource
{
/** @var int $currentUserId */
$currentUserId = Auth::id() ?? throw new UnauthenticatedException();

// This code is a nasty work-around which should not exist.
// PHP stores a temporary copy of the uploaded file without a file
// extension.
Expand Down Expand Up @@ -127,10 +132,10 @@ public function add(AddPhotoRequest $request): PhotoResource

// As the file has been uploaded, the (temporary) source file shall be
// deleted
$create = new Create(new ImportMode(
true,
Configs::getValueAsBool('skip_duplicates')
));
$create = new Create(
new ImportMode(deleteImported: true, skipDuplicates: Configs::getValueAsBool('skip_duplicates')),
$currentUserId
);

$photo = $create->add($copiedFile, $request->album());
$isNew = $photo->created_at->toIso8601String() === $photo->updated_at->toIso8601String();
Expand Down
2 changes: 1 addition & 1 deletion app/Metadata/Extractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ public static function createFromFile(NativeLocalFile $file): self
// to original timezone of the location where the video
// has been recorded.
// So we don't need to do anything.
//
//
// The only known example are the mov files from Apple
// devices; the time zone will be formatted as "+01:00"
// so neither of the two conditions above should trigger.
Expand Down
4 changes: 2 additions & 2 deletions app/Models/Extensions/AlbumBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ private function getTakenAtSQL(): Builder
// MySQL's built-in heuristic chooses that index with high
// priority and does not consider any alternatives.
// In this specific case, this heuristic fails splendidly.
//
//
// Further note, that PostgreSQL's optimizer is not affected
// by any of these tricks.
// The optimized query plan for PostgreSQL is always the same.
// Good PosgreSQL :-)
//
//
// We must not use `Album::query->` to start the query, but
// use a non-Eloquent query here to avoid an infinite loop
// with this query builder.
Expand Down