Skip to content

Commit

Permalink
Fix error 403 on access directly password protected albums (#2688)
Browse files Browse the repository at this point in the history
* fix error 503 on access directly password protected albums

* fix phpstan

* remove deprecated comment
  • Loading branch information
ildyria authored Nov 15, 2024
1 parent c83b5c9 commit 85f2359
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 23 deletions.
34 changes: 32 additions & 2 deletions app/Http/Controllers/VueController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

use App\Contracts\Models\AbstractAlbum;
use App\Exceptions\Internal\InvalidSmartIdException;
use App\Exceptions\UnauthorizedException;
use App\Factories\AlbumFactory;
use App\Models\Extensions\BaseAlbum;
use App\Models\Photo;
use App\Policies\AlbumPolicy;
use App\Policies\PhotoPolicy;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\View\View;
Expand All @@ -20,6 +23,9 @@
*/
class VueController extends Controller
{
public const ACCESS = 'access';
public const PASSWORD = 'password';

/**
* @param string|null $albumId
* @param string|null $photoId
Expand All @@ -37,13 +43,14 @@ public function view(?string $albumId = null, ?string $photoId = null): View
try {
if ($albumId !== null) {
$album = $albumFactory->findAbstractAlbumOrFail($albumId, false);
Gate::authorize(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $album]);

session()->now('access', $this->check($album));
session()->now('album', $album);
}

if ($photoId !== null) {
$photo = Photo::findOrFail($photoId);
Gate::authorize(\PhotoPolicy::CAN_SEE, [Photo::class, $photo]);
Gate::authorize(PhotoPolicy::CAN_SEE, [Photo::class, $photo]);
session()->now('photo', $photo);
}
} catch (ModelNotFoundException) {
Expand All @@ -52,4 +59,27 @@ public function view(?string $albumId = null, ?string $photoId = null): View

return view('vueapp');
}

/**
* Check if user can access the album.
*
* @param AbstractAlbum $album
*
* @return bool true if access, false if password required
*
* @throws UnauthorizedException if user is not authorized at all
*/
private function check(AbstractAlbum $album): bool
{
$result = Gate::check(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $album]);
if (
!$result &&
$album instanceof BaseAlbum &&
$album->public_permissions()?->password !== null
) {
return false;
}

return $result ? true : throw new UnauthorizedException();
}
}
59 changes: 39 additions & 20 deletions app/View/Components/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,41 +31,60 @@ class Meta extends Component
public string $userCssUrl;
public string $userJsUrl;

private bool $access = true;
private ?AbstractAlbum $album = null;
private ?Photo $photo = null;

/**
* Initialize the footer once for all.
*
* @throws ConfigurationKeyMissingException
*/
public function __construct()
{
// default data
$this->siteOwner = Configs::getValueAsString('site_owner');
$this->pageUrl = url()->current();
$this->rssEnable = Configs::getValueAsBool('rss_enable');
$this->userCssUrl = self::getUserCustomFiles('user.css');
$this->userJsUrl = self::getUserCustomFiles('custom.js');
$this->baseUrl = url('/');

$this->pageTitle = Configs::getValueAsString('site_title');
$this->pageDescription = '';
$this->imageUrl = '';
$this->imageUrl = Configs::getValueAsString('landing_background');

// processing photo and album data
if (session()->has('access')) {
$this->access = session()->get('access');
session()->forget('access');
}
if (session()->has('album')) {
/** @var AbstractAlbum $album */
$album = session()->get('album');
$this->pageTitle = $album->title;
if ($album instanceof BaseAlbum) {
$this->pageDescription = $album->description ?? Configs::getValueAsString('site_title');
}
$this->imageUrl = $this->getHeaderUrl($album) ?? '';
$this->album = session()->get('album');
session()->forget('album');
}

if (session()->has('photo')) {
/** @var Photo $photo */
$photo = session()->get('photo');
$this->pageTitle = $photo->title;
$this->pageDescription = $photo->description ?? Configs::getValueAsString('site_title');
$this->imageUrl = $photo->size_variants->getSmall()->url;
$this->photo = session()->get('photo');
session()->forget('photo');
}

$this->siteOwner = Configs::getValueAsString('site_owner');
$this->pageUrl = url()->current();
$this->rssEnable = Configs::getValueAsBool('rss_enable');
$this->userCssUrl = self::getUserCustomFiles('user.css');
$this->userJsUrl = self::getUserCustomFiles('custom.js');
$this->baseUrl = url('/');
if ($this->access === false) {
return;
}

if ($this->album !== null) {
$this->pageTitle = $this->album->title;
if ($this->album instanceof BaseAlbum) {
$this->pageDescription = $this->album->description ?? Configs::getValueAsString('site_title');
}
$this->imageUrl = $this->getHeaderUrl($this->album) ?? $this->imageUrl;
}

if ($this->photo !== null) {
$this->pageTitle = $this->photo->title;
$this->pageDescription = $this->photo->description ?? Configs::getValueAsString('site_title');
$this->imageUrl = $this->photo->size_variants->getSmall()->url;
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,4 @@ parameters:
- tests

-
message: '#Dynamic call to static method Illuminate\\Session\\Store::(has|get|now)\(\).#'
message: '#Dynamic call to static method Illuminate\\Session\\Store::(has|get|now|forget)\(\).#'

0 comments on commit 85f2359

Please sign in to comment.