diff options
author | dartcafe <github@dartcafe.de> | 2020-06-15 18:02:12 +0300 |
---|---|---|
committer | dartcafe <github@dartcafe.de> | 2020-06-15 18:02:12 +0300 |
commit | fe8bc1b4aa307e0d956994c0fdfef51a93f549b2 (patch) | |
tree | 6501a994cf729e46586dad04fdeb4d94bd1c5483 /lib | |
parent | 4632557dde1e437da3768e2baf1166d3056a3315 (diff) |
added shares to API
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Controller/ShareApiController.php | 167 | ||||
-rw-r--r-- | lib/Controller/ShareController.php | 157 | ||||
-rw-r--r-- | lib/Exceptions/InvalidUsername.php | 40 | ||||
-rw-r--r-- | lib/Service/ShareService.php | 246 |
4 files changed, 490 insertions, 120 deletions
diff --git a/lib/Controller/ShareApiController.php b/lib/Controller/ShareApiController.php new file mode 100644 index 00000000..bc04e376 --- /dev/null +++ b/lib/Controller/ShareApiController.php @@ -0,0 +1,167 @@ +<?php +/** + * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com> + * + * @author René Gieling <github@dartcafe.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Polls\Controller; + +use Exception; +use OCP\AppFramework\Db\DoesNotExistException; +use OCA\Polls\Exceptions\NotAuthorizedException; +use OCA\Polls\Exceptions\InvalidUsername; + + +use OCP\IRequest; +use OCP\AppFramework\ApiController; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; + +use OCA\Polls\Service\ShareService; + +class ShareApiController extends ApiController { + + private $shareService; + + /** + * ShareController constructor. + * @param string $appName + * @param string $userId + * @param IRequest $request + * @param ILogger $logger + * @param ShareService $shareService + */ + public function __construct( + string $appName, + IRequest $request, + ShareService $shareService + ) { + parent::__construct($appName, + $request, + 'POST, PUT, GET, DELETE', + 'Authorization, Content-Type, Accept', + 1728000); + $this->shareService = $shareService; + } + + /** + * getByToken + * Get pollId by token + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * @PublicPage + * @param string $token + * @return DataResponse + */ + public function get($token) { + try { + return new DataResponse($this->shareService->get($token), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (DoesNotExistException $e) { + return new DataResponse('Token ' . $token . ' not found', Http::STATUS_NOT_FOUND); + } + } + + /** + * get + * Read all shares of a poll based on the poll id and return list as array + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * @param integer $pollId + * @return DataResponse + */ + public function list($pollId) { + try { + return new DataResponse($this->shareService->list($pollId), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (DoesNotExistException $e) { + return new DataResponse('No shares for poll with id ' . $pollId . ' not found', Http::STATUS_NOT_FOUND); + } + } + + /** + * Write a new share to the db and returns the new share as array + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * @param int $pollId + * @param string $message + * @return DataResponse + */ + public function add($pollId, $type, $userId = '', $userEmail = '') { + try { + return new DataResponse($this->shareService->add($pollId, $type, $userId, $userEmail), Http::STATUS_CREATED); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (\Exception $e) { + return new DataResponse($e, Http::STATUS_CONFLICT); + } + + } + + /** + * createPersonalShare + * Write a new share to the db and returns the new share as array + * @NoAdminRequired + * @CORS + * @PublicPage + * @NoCSRFRequired + * @param int $pollId + * @param string $message + * @return DataResponse + */ + public function createPersonalShare($token, $userName) { + + try { + return new DataResponse($this->shareService->createPersonalShare($token, $userName), Http::STATUS_CREATED); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (InvalidUsername $e) { + return new DataResponse($userName . ' is not valid', Http::STATUS_CONFLICT); + } catch (DoesNotExistException $e) { + // return forbidden in all not catched error cases + return new DataResponse($e, Http::STATUS_FORBIDDEN); + } + } + + /** + * remove + * remove share + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * @param Share $share + * @return DataResponse + */ + + public function delete($token) { + try { + return new DataResponse($this->shareService->remove($token), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (Exception $e) { + return new DataResponse($e, Http::STATUS_NOT_FOUND); + } + } +} diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php index 15eee195..c2e769ad 100644 --- a/lib/Controller/ShareController.php +++ b/lib/Controller/ShareController.php @@ -25,6 +25,8 @@ namespace OCA\Polls\Controller; use Exception; use OCP\AppFramework\Db\DoesNotExistException; +use OCA\Polls\Exceptions\NotAuthorizedException; +use OCA\Polls\Exceptions\InvalidUsername; use OCP\IRequest; @@ -33,60 +35,36 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; -use OCP\Security\ISecureRandom; -use OCA\Polls\Db\Poll; use OCA\Polls\Model\Acl; -use OCA\Polls\Db\PollMapper; -use OCA\Polls\Db\Share; -use OCA\Polls\Db\ShareMapper; -use OCA\Polls\Service\MailService; -// TODO: Change to Service -use OCA\Polls\Controller\SystemController; +use OCA\Polls\Service\ShareService; class ShareController extends Controller { private $logger; - private $acl; - private $mapper; + private $shareService; private $userId; - private $pollMapper; - private $systemController; - private $mailService; - /** * ShareController constructor. * @param string $appName * @param string $userId * @param IRequest $request * @param ILogger $logger - * @param ShareMapper $mapper - * @param PollMapper $pollMapper - * @param SystemController $systemController - * @param MailService $mailService - * @param Acl $acl + * @param ShareService $shareService */ public function __construct( string $appName, $userId, IRequest $request, ILogger $logger, - ShareMapper $mapper, - PollMapper $pollMapper, - SystemController $systemController, - MailService $mailService, - Acl $acl + ShareService $shareService ) { parent::__construct($appName, $request); $this->logger = $logger; $this->userId = $userId; - $this->mapper = $mapper; - $this->pollMapper = $pollMapper; - $this->systemController = $systemController; - $this->mailService = $mailService; - $this->acl = $acl; + $this->shareService = $shareService; } /** @@ -100,11 +78,11 @@ class ShareController extends Controller { */ public function get($token) { try { - $share = $this->mapper->findByToken($token); - return new DataResponse($share, Http::STATUS_OK); - + return new DataResponse($this->shareService->get($token), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); } catch (DoesNotExistException $e) { - return new DataResponse(null, Http::STATUS_NOT_FOUND); + return new DataResponse('Token ' . $token . ' not found', Http::STATUS_NOT_FOUND); } } @@ -117,21 +95,13 @@ class ShareController extends Controller { * @return DataResponse */ public function getShares($pollId) { - if ($this->acl->setPollId($pollId)->getAllowEdit()) { - try { - $shares = $this->mapper->findByPoll($pollId); - return new DataResponse((array) $shares, Http::STATUS_OK); - - } catch (DoesNotExistException $e) { - return new DataResponse($e, Http::STATUS_NOT_FOUND); - } - - } else { - $this->logger->alert('no access'); - - return new DataResponse(null, Http::STATUS_UNAUTHORIZED); + try { + return new DataResponse($this->shareService->findByPoll($pollId), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (DoesNotExistException $e) { + return new DataResponse('No shares for poll with id ' . $pollId . ' not found', Http::STATUS_NOT_FOUND); } - } /** @@ -143,32 +113,16 @@ class ShareController extends Controller { * @return DataResponse */ public function write($pollId, $share) { - $this->acl->setPollId($pollId); - if (!$this->acl->getAllowEdit()) { - return new DataResponse(null, Http::STATUS_UNAUTHORIZED); - } - - $newShare = new Share(); - $newShare->setType($share['type']); - $newShare->setPollId($share['pollId']); - $newShare->setUserId($share['userId']); - $newShare->setUserEmail(isset($share['userEmail']) ? $share['userEmail'] : ''); - $newShare->setToken(\OC::$server->getSecureRandom()->generate( - 16, - ISecureRandom::CHAR_DIGITS . - ISecureRandom::CHAR_LOWER . - ISecureRandom::CHAR_UPPER - )); - try { - $newShare = $this->mapper->insert($newShare); - $sendResult = $this->mailService->sendInvitationMail($newShare->getToken()); - - return new DataResponse([ - 'share' => $newShare, - 'sendResult' => $sendResult - ], Http::STATUS_OK); - + $return = $this->shareService->write( + $pollId, + $share['type'], + $share['userId'], + isset($share['userEmail']) ? $share['userEmail'] : '' + ); + return new DataResponse($return, Http::STATUS_CREATED); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); } catch (\Exception $e) { return new DataResponse($e, Http::STATUS_CONFLICT); } @@ -188,43 +142,11 @@ class ShareController extends Controller { public function createPersonalShare($token, $userName) { try { - $publicShare = $this->mapper->findByToken($token); - - // Return of validatePublicUsername is a DataResponse - $checkUsername = $this->systemController->validatePublicUsername($publicShare->getPollId(), $userName, $token); - - // if status is not 200, return DataResponse from validatePublicUsername - if ($checkUsername->getStatus() !== 200) { - return $checkUsername; - } - - if ($publicShare->getType() === 'public') { - - $userShare = new Share(); - $userShare->setToken(\OC::$server->getSecureRandom()->generate( - 16, - ISecureRandom::CHAR_DIGITS . - ISecureRandom::CHAR_LOWER . - ISecureRandom::CHAR_UPPER - )); - $userShare->setType('external'); - $userShare->setPollId($publicShare->getPollId()); - $userShare->setUserId($userName); - $userShare->setUserEmail(''); - $userShare = $this->mapper->insert($userShare); - return new DataResponse($userShare, Http::STATUS_OK); - - } elseif ($publicShare->getType() === 'email') { - - $publicShare->setType('external'); - $publicShare->setUserId($userName); - $this->mapper->update($publicShare); - return new DataResponse($publicShare, Http::STATUS_OK); - - } else { - return new DataResponse(['message'=> 'Wrong share type: ' . $userShare->getType()], Http::STATUS_FORBIDDEN); - } - + return new DataResponse($this->shareService->createPersonalShare($token, $userName), Http::STATUS_CREATED); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); + } catch (InvalidUsername $e) { + return new DataResponse($userName . ' is not valid', Http::STATUS_CONFLICT); } catch (DoesNotExistException $e) { // return forbidden in all not catched error cases return new DataResponse($e, Http::STATUS_FORBIDDEN); @@ -242,17 +164,12 @@ class ShareController extends Controller { public function remove($share) { try { - if ($this->acl->setPollId($share['pollId'])->getAllowEdit()) { - $this->mapper->remove($share['id']); - - return new DataResponse(array( - 'action' => 'deleted', - 'shareId' => $share['id'] - ), Http::STATUS_OK); - } else { - return new DataResponse(null, Http::STATUS_UNAUTHORIZED); - } - + return new DataResponse(array( + 'action' => 'deleted', + 'shareId' => $this->shareService->remove($share['token'])->getId() + ), Http::STATUS_OK); + } catch (NotAuthorizedException $e) { + return new DataResponse('Unauthorized', Http::STATUS_FORBIDDEN); } catch (Exception $e) { return new DataResponse($e, Http::STATUS_NOT_FOUND); } diff --git a/lib/Exceptions/InvalidUsername.php b/lib/Exceptions/InvalidUsername.php new file mode 100644 index 00000000..b75c8ea0 --- /dev/null +++ b/lib/Exceptions/InvalidUsername.php @@ -0,0 +1,40 @@ +<?php +/** + * @copyright Copyright (c) 2020 René Gieling <github@dartcafe.de> + * + * @author René Gieling <github@dartcafe.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Polls\Exceptions; + +use OCP\AppFramework\Http; + +class InvalidUsername extends \Exception { + /** + * InvalidUsername Constructor + * @param string $e exception message + */ + public function __construct($e = 'Invalid username') { + parent::__construct($e); + } + public function getStatus() { + return Http::STATUS_CONFLICT; + } + +} diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php new file mode 100644 index 00000000..c362e97a --- /dev/null +++ b/lib/Service/ShareService.php @@ -0,0 +1,246 @@ +<?php +/** + * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com> + * + * @author René Gieling <github@dartcafe.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Polls\Service; + +use Exception; + +use OCP\ILogger; +use OCP\Security\ISecureRandom; + +use OCA\Polls\Exceptions\NotAuthorizedException; +use OCA\Polls\Exceptions\InvalidUsername; + +use OCA\Polls\Db\Poll; +use OCA\Polls\Db\PollMapper; +use OCA\Polls\Db\Share; +use OCA\Polls\Db\ShareMapper; +use OCA\Polls\Service\MailService; +use OCA\Polls\Model\Acl; +// TODO: Change to Service +use OCA\Polls\Controller\SystemController; + +class ShareService { + + private $logger; + private $acl; + private $shareMapper; + private $share; + private $userId; + + private $pollMapper; + private $systemController; + private $mailService; + + /** + * ShareController constructor. + * @param string $appName + * @param string $userId + * @param IRequest $request + * @param ILogger $logger + * @param ShareMapper $shareMapper + * @param Share $share + * @param PollMapper $pollMapper + * @param SystemController $systemController + * @param MailService $mailService + * @param Acl $acl + */ + public function __construct( + string $appName, + $userId, + ILogger $logger, + ShareMapper $shareMapper, + Share $share, + PollMapper $pollMapper, + SystemController $systemController, + MailService $mailService, + Acl $acl + ) { + $this->logger = $logger; + $this->userId = $userId; + $this->shareMapper = $shareMapper; + $this->share = $share; + $this->pollMapper = $pollMapper; + $this->systemController = $systemController; + $this->mailService = $mailService; + $this->acl = $acl; + } + + /** + * get + * Read all shares of a poll based on the poll id and return list as array + * @NoAdminRequired + * @param integer $pollId + * @return DataResponse + */ + public function list($pollId) { + if ($this->acl->setPollId($pollId)->getAllowEdit()) { + return $this->shareMapper->findByPoll($pollId); + } else { + throw new NotAuthorizedException; + } + } + + /** + * getByToken + * Get pollId by token + * @NoAdminRequired + * @param string $token + * @return Array + */ + public function get($token) { + $this->share = $this->shareMapper->findByToken($token); + return $this->share; + } + + /** + * Write a new share to the db and returns the new share as array + * @NoAdminRequired + * @depricated + * @param int $pollId + * @param string $share + * @return Array + */ + // TODO: Replace with $this->add and separate sending invitations + public function write($pollId, $type, $userId, $userEmail = '') { + $this->acl->setPollId($pollId); + if (!$this->acl->getAllowEdit()) { + throw new NotAuthorizedException; + } + + $this->share = new Share(); + $this->share->setType($type); + $this->share->setPollId($pollId); + $this->share->setUserId($userId); + $this->share->setUserEmail($userEmail); + $this->share->setToken(\OC::$server->getSecureRandom()->generate( + 16, + ISecureRandom::CHAR_DIGITS . + ISecureRandom::CHAR_LOWER . + ISecureRandom::CHAR_UPPER + )); + + $this->share = $this->shareMapper->insert($this->share); + $sendResult = $this->mailService->sendInvitationMail($this->share->getToken()); + + return [ + 'share' => $this->share, + 'sendResult' => $sendResult + ]; + } + + /** + * Write a new share to the db and returns the new share as array + * @NoAdminRequired + * @param int $pollId + * @param string $share + * @return Array + */ + public function add($pollId, $type, $userId, $userEmail = '') { + $this->acl->setPollId($pollId); + if (!$this->acl->getAllowEdit()) { + throw new NotAuthorizedException; + } + + $this->share = new Share(); + $this->share->setType($type); + $this->share->setPollId($pollId); + $this->share->setUserId($userId); + $this->share->setUserEmail($userEmail); + $this->share->setToken(\OC::$server->getSecureRandom()->generate( + 16, + ISecureRandom::CHAR_DIGITS . + ISecureRandom::CHAR_LOWER . + ISecureRandom::CHAR_UPPER + )); + + return $this->shareMapper->insert($this->share); + + } + + /** + * createPersonalShare + * Write a new share to the db and returns the new share as array + * @NoAdminRequired + * @param string $token + * @param string $userName + * @return Share + */ + public function createPersonalShare($token, $userName) { + + $publicShare = $this->shareMapper->findByToken($token); + + // Return of validatePublicUsername is a DataResponse + $checkUsername = $this->systemController->validatePublicUsername($publicShare->getPollId(), $userName, $token); + + // if status is not 200, return DataResponse from validatePublicUsername + if ($checkUsername->getStatus() !== 200) { + throw new InvalidUsername; + } + + if ($publicShare->getType() === 'public') { + + $this->share = new Share(); + $this->share->setToken(\OC::$server->getSecureRandom()->generate( + 16, + ISecureRandom::CHAR_DIGITS . + ISecureRandom::CHAR_LOWER . + ISecureRandom::CHAR_UPPER + )); + $this->share->setType('external'); + $this->share->setPollId($publicShare->getPollId()); + $this->share->setUserId($userName); + $this->share->setUserEmail(''); + $this->share = $this->shareMapper->insert($this->share); + return $this->share; + + } elseif ($publicShare->getType() === 'email') { + + $publicShare->setType('external'); + $publicShare->setUserId($userName); + $this->shareMapper->update($publicShare); + return new DataResponse($publicShare, Http::STATUS_OK); + + } else { + throw new NotAuthorizedException; + } + } + + /** + * remove + * remove share + * @NoAdminRequired + * @param string $token + * @return Share + */ + + public function remove($token) { + $this->share = $this->shareMapper->findByToken($token); + if ($this->acl->setPollId($this->share->getPollId())->getAllowEdit()) { + $this->shareMapper->delete($this->share); + return $this->share; + } else { + throw new NotAuthorizedException; + } + } +} |