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

Timeline settings + fix discovery of sensitive photos #2673

Merged
merged 2 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 4 additions & 2 deletions app/Actions/Albums/PositionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function __construct(PhotoQueryPolicy $photoQueryPolicy)
public function do(): PositionDataResource
{
$photoQuery = $this->photoQueryPolicy->applySearchabilityFilter(
Photo::query()
query: Photo::query()
->with([
'album' => function ($b) {
// The album is required for photos to properly
Expand All @@ -51,7 +51,9 @@ public function do(): PositionDataResource
'size_variants.sym_links',
])
->whereNotNull('latitude')
->whereNotNull('longitude')
->whereNotNull('longitude'),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_map')
);

return new PositionDataResource(null, null, $photoQuery->get(), null);
Expand Down
4 changes: 3 additions & 1 deletion app/Actions/RSS/Generate.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ public function do(): Collection
/** @var Collection<int,Photo> $photos */
$photos = $this->photoQueryPolicy
->applySearchabilityFilter(
Photo::query()->with(['album', 'owner', 'size_variants', 'size_variants.sym_links'])
query: Photo::query()->with(['album', 'owner', 'size_variants', 'size_variants.sym_links']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_rss')
)
->where('photos.created_at', '>=', $nowMinus)
->limit($rss_max)
Expand Down
6 changes: 4 additions & 2 deletions app/Actions/Search/PhotoSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\DTO\PhotoSortingCriterion;
use App\Eloquent\FixedQueryBuilder;
use App\Models\Album;
use App\Models\Configs;
use App\Models\Extensions\SortingDecorator;
use App\Models\Photo;
use App\Policies\PhotoQueryPolicy;
Expand Down Expand Up @@ -50,8 +51,9 @@ public function query(array $terms): Collection
public function sqlQuery(array $terms, ?Album $album = null): Builder
{
$query = $this->photoQueryPolicy->applySearchabilityFilter(
Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
$album
query: Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
origin: $album,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_search')
);

foreach ($terms as $term) {
Expand Down
6 changes: 5 additions & 1 deletion app/Http/Controllers/Gallery/FrameController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ private function loadPhoto(AbstractAlbum|null $album, int $retries = 5): ?Photo

// default query
if ($album === null) {
$query = $this->photoQueryPolicy->applySearchabilityFilter(Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']));
$query = $this->photoQueryPolicy->applySearchabilityFilter(
query: Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_frame')
);
} else {
$query = $album->photos()->with(['album', 'size_variants', 'size_variants.sym_links']);
}
Expand Down
5 changes: 4 additions & 1 deletion app/Legacy/V1/Controllers/PhotoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ public function getRandom(PhotoQueryPolicy $photoQueryPolicy): PhotoResource
$randomAlbumId = Configs::getValueAsString('random_album_id');

if ($randomAlbumId === '') {
$query = $photoQueryPolicy->applySearchabilityFilter(Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']));
$query = $photoQueryPolicy->applySearchabilityFilter(
query: Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_frame'));
} else {
$query = $this->albumFactory->findAbstractAlbumOrFail($randomAlbumId)
->photos()
Expand Down
28 changes: 28 additions & 0 deletions app/Models/Extensions/AbstractBaseConfigMigration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Models\Extensions;

use Illuminate\Database\Migrations\Migration;

abstract class AbstractBaseConfigMigration extends Migration
{
public const BOOL = '0|1';
public const POSITIVE = 'positive';
public const INT = 'int';
public const STRING = 'string';

/**
* @return array<int,array{key:string,value:string,is_secret:bool,cat:string,type_range:string,description:string}>
*/
abstract public function getConfigs(): array;

/**
* Run the migrations.
*/
abstract public function up(): void;

/**
* Reverse the migrations.
*/
abstract public function down(): void;
}
13 changes: 1 addition & 12 deletions app/Models/Extensions/BaseConfigMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,10 @@

namespace App\Models\Extensions;

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

abstract class BaseConfigMigration extends Migration
abstract class BaseConfigMigration extends AbstractBaseConfigMigration
{
public const BOOL = '0|1';
public const POSITIVE = 'positive';
public const INT = 'int';
public const STRING = 'string';

/**
* @return array<int,array{key:string,value:string,is_secret:bool,cat:string,type_range:string,description:string}>
*/
abstract public function getConfigs(): array;

/**
* Run the migrations.
*/
Expand Down
25 changes: 25 additions & 0 deletions app/Models/Extensions/BaseConfigMigrationReversed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Models\Extensions;

use Illuminate\Support\Facades\DB;

abstract class BaseConfigMigrationReversed extends AbstractBaseConfigMigration
{
/**
* Run the migrations.
*/
final public function up(): void
{
$keys = collect($this->getConfigs())->map(fn ($v) => $v['key'])->all();
DB::table('configs')->whereIn('key', $keys)->delete();
}

/**
* Reverse the migrations.
*/
final public function down(): void
{
DB::table('configs')->insert($this->getConfigs());
}
}
20 changes: 10 additions & 10 deletions app/Policies/PhotoQueryPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use App\Exceptions\Internal\InvalidQueryModelException;
use App\Exceptions\Internal\QueryBuilderException;
use App\Models\Album;
use App\Models\Configs;
use App\Models\Photo;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as BaseBuilder;
Expand Down Expand Up @@ -87,14 +86,15 @@ public function applyVisibilityFilter(FixedQueryBuilder $query): FixedQueryBuild
* The method simply assumes that the user has already legitimately
* accessed the origin album, if the caller provides an album model.
*
* @param FixedQueryBuilder<Photo> $query the photo query which shall be restricted
* @param Album|null $origin the optional top album which is used as a search base
* @param FixedQueryBuilder<Photo> $query the photo query which shall be restricted
* @param Album|null $origin the optional top album which is used as a search base
* @param bool $include_nsfw include also the photos in sensitive albums
*
* @return FixedQueryBuilder<Photo> the restricted photo query
*
* @throws InternalLycheeException
*/
public function applySearchabilityFilter(FixedQueryBuilder $query, ?Album $origin = null): FixedQueryBuilder
public function applySearchabilityFilter(FixedQueryBuilder $query, ?Album $origin = null, bool $include_nsfw = true): FixedQueryBuilder
{
$this->prepareModelQueryOrFail($query, true, false);

Expand All @@ -107,7 +107,7 @@ public function applySearchabilityFilter(FixedQueryBuilder $query, ?Album $origi
->where('albums._rgt', '<=', $origin->_rgt);
}

if (Configs::getValueAsBool('hide_nsfw_in_smart_albums_and_search')) {
if (!$include_nsfw) {
$query->where(fn (Builder $query) => $this->appendSensitivityConditions($query->getQuery(), $origin?->_lft, $origin?->_rgt));
}

Expand Down Expand Up @@ -232,11 +232,11 @@ public function appendSensitivityConditions(BaseBuilder $query, int|string|null
// root album, they must only see their own photos or public
// photos (this is different to any other album: if users are
// allowed to access an album, they may also see its content)
$query->orWhereNull('photos.album_id');

if ($userId !== null) {
$query->orWhere('photos.owner_id', '=', $userId);
}
$query->orWhere(
fn ($q) => $q
->whereNull('photos.album_id')
->where('photos.owner_id', '=', $userId)
);
} catch (\Throwable $e) {
throw new QueryBuilderException($e);
}
Expand Down
5 changes: 4 additions & 1 deletion app/Relations/HasAlbumThumb.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ public function addConstraints(): void
$this->where('photos.id', '=', $album->cover_id);
} else {
$this->photoQueryPolicy
->applySearchabilityFilter($this->getRelationQuery(), $album);
->applySearchabilityFilter(
query: $this->getRelationQuery(),
origin: $album,
include_nsfw: $album->is_nsfw);
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion app/Relations/HasManyPhotosByTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Contracts\Exceptions\InternalLycheeException;
use App\Enum\OrderSortingType;
use App\Exceptions\Internal\NotImplementedException;
use App\Models\Configs;
use App\Models\Extensions\SortingDecorator;
use App\Models\TagAlbum;
use Illuminate\Database\Eloquent\Builder;
Expand Down Expand Up @@ -63,7 +64,11 @@ public function addEagerConstraints(array $albums): void
$tags = $album->show_tags;

$this->photoQueryPolicy
->applySearchabilityFilter($this->getRelationQuery())
->applySearchabilityFilter(
$this->getRelationQuery(),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)
->where(function (Builder $q) use ($tags) {
// Filter for requested tags
foreach ($tags as $tag) {
Expand Down
6 changes: 5 additions & 1 deletion app/Relations/HasManyPhotosRecursively.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ public function addEagerConstraints(array $albums): void
}

$this->photoQueryPolicy
->applySearchabilityFilter($this->getRelationQuery(), $albums[0]);
->applySearchabilityFilter(
query: $this->getRelationQuery(),
origin: $albums[0],
include_nsfw: true
);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion app/SmartAlbums/BaseSmartAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ public function photos(): Builder
{
$query = $this->photoQueryPolicy
->applySearchabilityFilter(
Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links'])
query: Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)->where($this->smartPhotoCondition);

return $query;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
use App\Models\Extensions\BaseConfigMigration;

return new class() extends BaseConfigMigration {
public const OAUTH = 'OAuth & SSO';

public function getConfigs(): array
{
return [
Expand Down
Loading