<?php /** * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2020-2021 (original work) Open Assessment Technologies SA; * */ declare(strict_types=1); namespace oat\taoMediaManager\controller; use common_session_SessionManager; use oat\oatbox\log\LoggerAwareTrait; use oat\tao\model\accessControl\data\DataAccessControl; use oat\tao\model\http\formatter\ResponseFormatter; use oat\tao\model\http\response\ErrorJsonResponse; use oat\tao\model\http\response\SuccessJsonResponse; use oat\tao\model\resources\ResourceAccessDeniedException; use oat\taoMediaManager\model\sharedStimulus\factory\CommandFactory; use oat\taoMediaManager\model\sharedStimulus\factory\QueryFactory; use oat\taoMediaManager\model\sharedStimulus\parser\JsonQtiAttributeParser; use oat\taoMediaManager\model\sharedStimulus\repository\SharedStimulusRepository; use oat\taoMediaManager\model\sharedStimulus\service\CreateService; use oat\taoMediaManager\model\sharedStimulus\SharedStimulus as SharedStimulusObject; use oat\taoMediaManager\model\sharedStimulus\service\PatchService; use tao_actions_SaSModule; use Throwable; class SharedStimulus extends tao_actions_SaSModule { use LoggerAwareTrait; private const PERMISSION_READ = 'READ'; /** * @requiresRight classUri WRITE */ public function create(): void { $formatter = $this->getResponseFormatter() ->withJsonHeader(); try { $command = $this->getCommandFactory() ->makeCreateCommandByRequest($this->getPsrRequest()); $this->validateWritePermission($command->getClassId()); $sharedStimulus = $this->getCreateService() ->create($command); $this->renderSharedStimulus($formatter, $sharedStimulus); } catch (Throwable $exception) { $this->logError(sprintf('Error creating Shared Stimulus: %s', $exception->getMessage())); $formatter->withStatusCode(400) ->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage())); } $this->setResponse($formatter->format($this->getPsrResponse())); } /** * @requiresRight id READ */ public function get(): void { $formatter = $this->getResponseFormatter() ->withJsonHeader(); try { $command = $this->getQueryFactory() ->makeFindQueryByRequest($this->getPsrRequest()); $this->validateReadPermission($command->getId()); $sharedStimulus = $this->getSharedStimulusRepository() ->find($command); $this->renderSharedStimulus($formatter, $sharedStimulus); } catch (Throwable $exception) { $this->logError(sprintf('Error retrieving Shared Stimulus: %s', $exception->getMessage())); $formatter->withStatusCode(400) ->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage())); } $this->setResponse($formatter->format($this->getPsrResponse())); } /** * @requiresRight id WRITE */ public function patch(): void { $formatter = $this->getResponseFormatter() ->withJsonHeader(); try { $request = $this->getPsrRequest(); $user = common_session_SessionManager::getSession()->getUser(); $id = $request->getQueryParams()['id']; $body = json_decode((string)$request->getBody(), true)['body']; $this->validateWritePermission($id); $command = $this->getCommandFactory()->makePatchCommand($id, $body, $user); $this->getPatchService()->patch($command); $formatter->withBody(new SuccessJsonResponse([])); } catch (Throwable $exception) { $this->logError(sprintf('Error Updating Shared Stimulus: %s', $exception->getMessage())); $formatter->withStatusCode(400) ->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage())); } $this->setResponse($formatter->format($this->getPsrResponse())); } private function renderSharedStimulus(ResponseFormatter $formatter, SharedStimulusObject $sharedStimulus): void { $data = $sharedStimulus->jsonSerialize(); if (isset($data['body'])) { $data['body'] = $this->getSharedStimulusAttributesParser()->parse($sharedStimulus); } $data['permissions'] = $this->getPreviewPermission(); $formatter->withBody(new SuccessJsonResponse($data)); } private function getPreviewPermission(): array { if ($this->hasAccess(MediaManager::class, 'getFile')) { return [self::PERMISSION_READ]; } return []; } private function getResponseFormatter(): ResponseFormatter { return $this->getServiceLocator()->get(ResponseFormatter::class); } private function getCommandFactory(): CommandFactory { return $this->getServiceLocator()->get(CommandFactory::class); } private function getQueryFactory(): QueryFactory { return $this->getServiceLocator()->get(QueryFactory::class); } private function getCreateService(): CreateService { return $this->getServiceLocator()->get(CreateService::class); } private function getPatchService(): PatchService { return $this->getServiceLocator()->get(PatchService::class); } private function getSharedStimulusRepository(): SharedStimulusRepository { return $this->getServiceLocator()->get(SharedStimulusRepository::class); } private function getSharedStimulusAttributesParser(): JsonQtiAttributeParser { return $this->getServiceLocator()->get(JsonQtiAttributeParser::class); } private function validateWritePermission(string $resourceId): void { if (!$this->hasWriteAccess($resourceId)) { throw new ResourceAccessDeniedException($resourceId); } } private function validateReadPermission(string $resourceId): void { $user = $this->getSession()->getUser(); $hasReadAccess = (new DataAccessControl())->hasPrivileges($user, [$resourceId => 'READ']); if (!$hasReadAccess) { throw new ResourceAccessDeniedException($resourceId); } } }