generated from Nodarx/template
92e85aed47
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
58 lines
3.0 KiB
PHP
58 lines
3.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace KTXM\ServiceWopi\Host;
|
|
|
|
use KTXC\Service\TenantService;
|
|
use KTXC\Stores\UserAccountsStore;
|
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
|
use KTXF\Resource\Identifier\ResourceIdentifier;
|
|
use KTXM\DocumentsManager\Manager;
|
|
use KTXM\ProviderLocalDocuments\Providers\Personal\PersonalService;
|
|
|
|
class Documents
|
|
{
|
|
public function __construct(private readonly Manager $manager, private readonly UserAccountsStore $users, private readonly TenantService $tenants) {}
|
|
|
|
public function authorize(string $tenant, string $user): void
|
|
{
|
|
$account = $this->users->fetchByIdentifier($tenant, $user);
|
|
if (!$this->tenants->fetchById($tenant)?->getEnabled() || !($account['enabled'] ?? false)) {
|
|
throw new HostException('Document access is unavailable.', 404);
|
|
}
|
|
$roles = (array) ($account['roles'] ?? []);
|
|
$permissions = (array) ($account['permissions'] ?? []);
|
|
if (!array_intersect(['admin', 'system.admin'], $roles)
|
|
&& !array_intersect(['*', 'service_wopi.*', 'service_wopi.view'], $permissions)) {
|
|
throw new HostException('Document access is unavailable.', 404);
|
|
}
|
|
}
|
|
|
|
/** @return array{label: string, content: string, version: string, size: int} */
|
|
public function read(string $tenant, string $user, string $resource, int $maxBytes): array
|
|
{
|
|
$this->authorize($tenant, $user);
|
|
$id = ResourceIdentifier::fromString($resource);
|
|
if (!$id instanceof EntityIdentifier || $id->provider() !== 'default' || $id->service() !== 'personal') {
|
|
throw new HostException('This storage provider is not available for office viewing.', 404);
|
|
}
|
|
$service = $this->manager->serviceFetch($tenant, $user, $id->provider(), $id->service());
|
|
if (!$service instanceof PersonalService || !$service->getEnabled()) {
|
|
throw new HostException('Document access is unavailable.', 404);
|
|
}
|
|
$entity = $this->manager->entityFetchBulk($tenant, $user, $id)[$resource] ?? null;
|
|
if ($entity === null) { throw new HostException('Document access is unavailable.', 404); }
|
|
if ($entity->getProperties()->size() > $maxBytes) { throw new HostException('Document exceeds the office viewing size limit.', 413); }
|
|
$stream = $service->entityReadStream($id);
|
|
if (!is_resource($stream)) { throw new HostException('Document access is unavailable.', 404); }
|
|
try {
|
|
$content = stream_get_contents($stream, $maxBytes + 1);
|
|
} finally {
|
|
fclose($stream);
|
|
}
|
|
if ($content === false) { throw new HostException('Could not read the document.', 503); }
|
|
if (strlen($content) > $maxBytes) { throw new HostException('Document exceeds the office viewing size limit.', 413); }
|
|
$label = $entity->getProperties()->getLabel();
|
|
return ['label' => $label, 'content' => $content, 'version' => hash('sha256', $label . "\0" . $content), 'size' => strlen($content)];
|
|
}
|
|
}
|