misuzu/src/Http/Handlers/AssetsHandler.php

108 lines
3.9 KiB
PHP
Raw Normal View History

2022-09-13 13:14:49 +00:00
<?php
namespace Misuzu\Http\Handlers;
use RuntimeException;
2022-09-13 13:14:49 +00:00
use Misuzu\GitInfo;
use Misuzu\Users\UserInfo;
2022-09-13 13:14:49 +00:00
use Misuzu\Users\Assets\StaticUserImageAsset;
use Misuzu\Users\Assets\UserAssetScalableInterface;
use Misuzu\Users\Assets\UserAvatarAsset;
use Misuzu\Users\Assets\UserBackgroundAsset;
use Misuzu\Users\Assets\UserImageAssetInterface;
2022-09-13 13:14:49 +00:00
final class AssetsHandler extends Handler {
private function canViewAsset($request, UserInfo $assetUser): bool {
return !$this->context->hasActiveBan($assetUser) || (
$this->context->isLoggedIn()
2022-09-13 13:14:49 +00:00
&& parse_url($request->getHeaderFirstLine('Referer'), PHP_URL_PATH) === url('user-profile')
&& perms_check_user(MSZ_PERMS_USER, $this->context->getActiveUser()->getId(), MSZ_PERM_USER_MANAGE_USERS)
2022-09-13 13:14:49 +00:00
);
}
private function serveUserAsset($response, $request, UserImageAssetInterface $assetInfo): void {
$contentType = $assetInfo->getMimeType();
$publicPath = $assetInfo->getPublicPath();
$fileName = $assetInfo->getFileName();
if($assetInfo instanceof UserAssetScalableInterface) {
$dimensions = (int)($request->getParam('res', FILTER_SANITIZE_NUMBER_INT) ?? $request->getParam('r', FILTER_SANITIZE_NUMBER_INT));
if($dimensions > 0) {
$assetInfo->ensureScaledExists($dimensions);
$contentType = $assetInfo->getScaledMimeType($dimensions);
$publicPath = $assetInfo->getPublicScaledPath($dimensions);
$fileName = $assetInfo->getScaledFileName($dimensions);
}
}
$response->accelRedirect($publicPath);
$response->setContentType($contentType);
$response->setFileName($fileName, false);
}
public function serveAvatar($response, $request, string $fileName) {
$userId = (int)pathinfo($fileName, PATHINFO_FILENAME);
2022-09-13 13:14:49 +00:00
$type = pathinfo($fileName, PATHINFO_EXTENSION);
if($type !== '' && $type !== 'png')
return 404;
$assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/no-avatar.png', MSZ_PUBLIC);
try {
$userInfo = $this->context->getUsers()->getUser($userId, 'id');
2022-09-13 13:14:49 +00:00
if(!$this->canViewAsset($request, $userInfo)) {
$assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/banned-avatar.png', MSZ_PUBLIC);
} else {
$userAssetInfo = new UserAvatarAsset($userInfo);
if($userAssetInfo->isPresent())
$assetInfo = $userAssetInfo;
2022-09-13 13:14:49 +00:00
}
} catch(RuntimeException $ex) {}
2022-09-13 13:14:49 +00:00
$this->serveUserAsset($response, $request, $assetInfo);
}
public function serveProfileBackground($response, $request, string $fileName) {
$userId = (int)pathinfo($fileName, PATHINFO_FILENAME);
2022-09-13 13:14:49 +00:00
$type = pathinfo($fileName, PATHINFO_EXTENSION);
if($type !== '' && $type !== 'png')
return 404;
try {
$userInfo = $this->context->getUsers()->getUser($userId, 'id');
} catch(RuntimeException $ex) {}
2022-09-13 13:14:49 +00:00
if(!empty($userInfo)) {
$userAssetInfo = new UserBackgroundAsset($userInfo);
if($userAssetInfo->isPresent() && $this->canViewAsset($request, $userInfo))
$assetInfo = $userAssetInfo;
}
if(!isset($assetInfo)) {
2022-09-13 13:14:49 +00:00
$response->setContent('');
return 404;
}
$this->serveUserAsset($response, $request, $assetInfo);
2022-09-13 13:14:49 +00:00
}
public function serveLegacy($response, $request) {
$assetUserId = $request->getParam('u', FILTER_SANITIZE_NUMBER_INT);
2022-09-13 13:14:49 +00:00
switch($request->getParam('m')) {
case 'avatar':
$this->serveAvatar($response, $request, $assetUserId);
return;
case 'background':
$this->serveProfileBackground($response, $request, $assetUserId);
return;
}
$response->setContent('');
return 404;
}
}