diff options
author | Luka Trovic <luka@nextcloud.com> | 2022-09-13 20:14:59 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2022-10-21 19:08:19 +0300 |
commit | 1217b37b19127305ce77340e69765c6b244c2cf3 (patch) | |
tree | 5903f71ae87e72a5f8cdabad001432fcd75c2cfc /lib | |
parent | f9acf7778feb3d684534433108b01e34cd401183 (diff) |
feat: add validators to check values in services
Signed-off-by: Luka Trovic <luka@nextcloud.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Service/AssignmentService.php | 27 | ||||
-rw-r--r-- | lib/Service/AttachmentService.php | 46 | ||||
-rw-r--r-- | lib/Service/BoardService.php | 101 | ||||
-rw-r--r-- | lib/Service/CardService.php | 100 | ||||
-rw-r--r-- | lib/Service/LabelService.php | 42 | ||||
-rw-r--r-- | lib/Service/StackService.php | 42 | ||||
-rw-r--r-- | lib/Validators/AssignmentServiceValidator.php | 37 | ||||
-rw-r--r-- | lib/Validators/AttachmentServiceValidator.php | 37 | ||||
-rw-r--r-- | lib/Validators/BaseValidator.php | 182 | ||||
-rw-r--r-- | lib/Validators/BoardServiceValidator.php | 47 | ||||
-rw-r--r-- | lib/Validators/CardServiceValidator.php | 44 | ||||
-rw-r--r-- | lib/Validators/LabelServiceValidator.php | 39 | ||||
-rw-r--r-- | lib/Validators/StackServiceValidator.php | 39 |
13 files changed, 511 insertions, 272 deletions
diff --git a/lib/Service/AssignmentService.php b/lib/Service/AssignmentService.php index 96965f01..3e69948f 100644 --- a/lib/Service/AssignmentService.php +++ b/lib/Service/AssignmentService.php @@ -35,6 +35,7 @@ use OCA\Deck\Event\CardUpdatedEvent; use OCA\Deck\NoPermissionException; use OCA\Deck\NotFoundException; use OCA\Deck\Notification\NotificationHelper; +use OCA\Deck\Validators\AssignmentServiceValidator; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\MultipleObjectsReturnedException; @@ -76,6 +77,11 @@ class AssignmentService { private $eventDispatcher; /** @var string|null */ private $currentUser; + /** + * @var AssignmentServiceValidator + */ + private $assignmentServiceValidator; + public function __construct( PermissionService $permissionService, @@ -86,8 +92,10 @@ class AssignmentService { ActivityManager $activityManager, ChangeHelper $changeHelper, IEventDispatcher $eventDispatcher, + AssignmentServiceValidator $assignmentServiceValidator, $userId ) { + $this->assignmentServiceValidator = $assignmentServiceValidator; $this->permissionService = $permissionService; $this->cardMapper = $cardMapper; $this->assignedUsersMapper = $assignedUsersMapper; @@ -96,6 +104,8 @@ class AssignmentService { $this->changeHelper = $changeHelper; $this->activityManager = $activityManager; $this->eventDispatcher = $eventDispatcher; + + $this->assignmentServiceValidator->check(compact('userId')); $this->currentUser = $userId; } @@ -109,13 +119,7 @@ class AssignmentService { * @throws DoesNotExistException */ public function assignUser($cardId, $userId, int $type = Assignment::TYPE_USER) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('user id must be provided'); - } + $this->assignmentServiceValidator->check(compact('cardId', 'userId')); if ($type !== Assignment::TYPE_USER && $type !== Assignment::TYPE_GROUP) { throw new BadRequestException('Invalid type provided for assignemnt'); @@ -168,16 +172,9 @@ class AssignmentService { * @throws MultipleObjectsReturnedException */ public function unassignUser($cardId, $userId, $type = 0) { + $this->assignmentServiceValidator->check(compact('cardId', 'userId')); $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('user must be provided'); - } - $assignments = $this->assignedUsersMapper->findAll($cardId); foreach ($assignments as $assignment) { if ($assignment->getParticipant() === $userId && $assignment->getType() === $type) { diff --git a/lib/Service/AttachmentService.php b/lib/Service/AttachmentService.php index c7c4532a..f9eb9682 100644 --- a/lib/Service/AttachmentService.php +++ b/lib/Service/AttachmentService.php @@ -36,6 +36,7 @@ use OCA\Deck\NoPermissionException; use OCA\Deck\NotFoundException; use OCA\Deck\Cache\AttachmentCacheHelper; use OCA\Deck\StatusException; +use OCA\Deck\Validators\AttachmentServiceValidator; use OCP\AppFramework\Db\IMapperException; use OCP\AppFramework\Http\Response; use OCP\IL10N; @@ -60,17 +61,22 @@ class AttachmentService { /** @var ChangeHelper */ private $changeHelper; private IUserManager $userManager; - - public function __construct(AttachmentMapper $attachmentMapper, - CardMapper $cardMapper, - IUserManager $userManager, - ChangeHelper $changeHelper, - PermissionService $permissionService, - Application $application, - AttachmentCacheHelper $attachmentCacheHelper, - $userId, - IL10N $l10n, - ActivityManager $activityManager) { + /** @var AttachmentServiceValidator */ + private AttachmentServiceValidator $attachmentServiceValidator; + + public function __construct( + AttachmentMapper $attachmentMapper, + CardMapper $cardMapper, + IUserManager $userManager, + ChangeHelper $changeHelper, + PermissionService $permissionService, + Application $application, + AttachmentCacheHelper $attachmentCacheHelper, + $userId, + IL10N $l10n, + ActivityManager $activityManager, + AttachmentServiceValidator $attachmentServiceValidator + ) { $this->attachmentMapper = $attachmentMapper; $this->cardMapper = $cardMapper; $this->permissionService = $permissionService; @@ -81,6 +87,7 @@ class AttachmentService { $this->activityManager = $activityManager; $this->changeHelper = $changeHelper; $this->userManager = $userManager; + $this->attachmentServiceValidator = $attachmentServiceValidator; // Register shipped attachment services // TODO: move this to a plugin based approach once we have different types of attachments @@ -187,17 +194,7 @@ class AttachmentService { * @throws BadRequestException */ public function create($cardId, $type, $data) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($data === false || $data === null) { - //throw new BadRequestException('data must be provided'); - } + $this->attachmentServiceValidator->check(compact('cardId', 'type', 'data')); $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); @@ -283,6 +280,8 @@ class AttachmentService { * @throws NoPermissionException */ public function update($cardId, $attachmentId, $data, $type = 'deck_file') { + $this->attachmentServiceValidator->check(compact('cardId', 'type', 'data')); + try { $service = $this->getService($type); } catch (InvalidAttachmentType $e) { @@ -304,9 +303,6 @@ class AttachmentService { } } - if ($data === false || $data === null) { - //throw new BadRequestException('data must be provided'); - } try { $attachment = $this->attachmentMapper->find($attachmentId); } catch (\Exception $e) { diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 01c56010..b63b5775 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -54,6 +54,7 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\BoardServiceValidator; use OCP\IURLGenerator; use OCP\Server; use Psr\Container\ContainerExceptionInterface; @@ -79,6 +80,7 @@ class BoardService { private ?array $boardsCache = null; private IURLGenerator $urlGenerator; private IDBConnection $connection; + private BoardServiceValidator $boardServiceValidator; public function __construct( BoardMapper $boardMapper, @@ -98,6 +100,7 @@ class BoardService { ChangeHelper $changeHelper, IURLGenerator $urlGenerator, IDBConnection $connection, + BoardServiceValidator $boardServiceValidator, ?string $userId ) { $this->boardMapper = $boardMapper; @@ -118,6 +121,7 @@ class BoardService { $this->urlGenerator = $urlGenerator; $this->cardMapper = $cardMapper; $this->connection = $connection; + $this->boardServiceValidator = $boardServiceValidator; } /** @@ -182,6 +186,7 @@ class BoardService { * @throws BadRequestException */ public function find($boardId) { + $this->boardServiceValidator->check(compact('boardId')); if ($this->boardsCache && isset($this->boardsCache[$boardId])) { return $this->boardsCache[$boardId]; } @@ -236,9 +241,7 @@ class BoardService { * @throws BadRequestException */ public function isArchived($mapper, $id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); try { $boardId = $id; @@ -265,13 +268,7 @@ class BoardService { * @throws BadRequestException */ public function isDeleted($mapper, $id) { - if ($mapper === false || $mapper === null) { - throw new BadRequestException('mapper must be provided'); - } - - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('mapper', 'id')); try { $boardId = $id; @@ -297,17 +294,7 @@ class BoardService { * @throws BadRequestException */ public function create($title, $userId, $color) { - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('userId must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } + $this->boardServiceValidator->check(compact('title', 'userId', 'color')); if (!$this->permissionService->canCreate()) { throw new NoPermissionException('Creating boards has been disabled for your account.'); @@ -358,9 +345,7 @@ class BoardService { * @throws BadRequestException */ public function delete($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -383,9 +368,7 @@ class BoardService { * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException */ public function deleteUndo($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -406,9 +389,7 @@ class BoardService { * @throws BadRequestException */ public function deleteForce($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -429,21 +410,7 @@ class BoardService { * @throws BadRequestException */ public function update($id, $title, $color, $archived) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } - - if (is_bool($archived) === false) { - throw new BadRequestException('archived must be a boolean'); - } + $this->boardServiceValidator->check(compact('id', 'title', 'color', 'archived')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -493,29 +460,7 @@ class BoardService { * @throws \OCA\Deck\NoPermissionException */ public function addAcl($boardId, $type, $participant, $edit, $share, $manage) { - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($participant === false || $participant === null) { - throw new BadRequestException('participant must be provided'); - } - - if ($edit === null) { - throw new BadRequestException('edit must be provided'); - } - - if ($share === null) { - throw new BadRequestException('share must be provided'); - } - - if ($manage === null) { - throw new BadRequestException('manage must be provided'); - } + $this->boardServiceValidator->check(compact('boardId', 'type', 'participant', 'edit', 'share', 'manage')); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_SHARE); [$edit, $share, $manage] = $this->applyPermissions($boardId, $edit, $share, $manage); @@ -561,21 +506,7 @@ class BoardService { * @throws BadRequestException */ public function updateAcl($id, $edit, $share, $manage) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } - - if ($edit === null) { - throw new BadRequestException('edit must be provided'); - } - - if ($share === null) { - throw new BadRequestException('share must be provided'); - } - - if ($manage === null) { - throw new BadRequestException('manage must be provided'); - } + $this->boardServiceValidator->check(compact('id', 'edit', 'share', 'manage')); $this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE); @@ -643,9 +574,7 @@ class BoardService { * @throws BadRequestException */ public function clone($id, $userId) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id', 'userId')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_READ); diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index af0eb010..95dbcf59 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -43,6 +43,7 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCA\Deck\StatusException; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\CardServiceValidator; use OCP\Comments\ICommentsManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\IRequest; @@ -69,6 +70,7 @@ class CardService { private IURLGenerator $urlGenerator; private LoggerInterface $logger; private IRequest $request; + private CardServiceValidator $cardServiceValidator; public function __construct( CardMapper $cardMapper, @@ -88,6 +90,7 @@ class CardService { IURLGenerator $urlGenerator, LoggerInterface $logger, IRequest $request, + CardServiceValidator $cardServiceValidator, ?string $userId ) { $this->cardMapper = $cardMapper; @@ -108,6 +111,7 @@ class CardService { $this->urlGenerator = $urlGenerator; $this->logger = $logger; $this->request = $request; + $this->cardServiceValidator = $cardServiceValidator; } public function enrich($card) { @@ -130,6 +134,7 @@ class CardService { } public function fetchDeleted($boardId) { + $this->cardServiceValidator->check(compact('boardId')); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); $cards = $this->cardMapper->findDeleted($boardId); foreach ($cards as $card) { @@ -190,29 +195,7 @@ class CardService { * @throws BadrequestException */ public function create($title, $stackId, $type, $order, $owner, $description = '', $duedate = null) { - if ($title === 'false' || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } - - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number'); - } - - if ($type === 'false' || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } - - if ($owner === false || $owner === null) { - throw new BadRequestException('owner must be provided'); - } + $this->cardServiceValidator->check(compact('title', 'stackId', 'type', 'order', 'owner')); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->stackMapper, $stackId)) { @@ -282,29 +265,7 @@ class CardService { * @throws BadRequestException */ public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null) { - if (is_numeric($id) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } - - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number $$$'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($owner === false || $owner === null) { - throw new BadRequestException('owner must be provided'); - } + $this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order')); $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); @@ -387,17 +348,7 @@ class CardService { * @throws BadRequestException */ public function rename($id, $title) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } + $this->cardServiceValidator->check(compact('id', 'title')); $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -428,17 +379,8 @@ class CardService { * @throws BadRequestException */ public function reorder($id, $stackId, $order) { - if (is_numeric($id) === false) { - throw new BadRequestException('card id must be a number'); - } + $this->cardServiceValidator->check(compact('id', 'stackId', 'order')); - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); @@ -493,9 +435,8 @@ class CardService { * @throws BadRequestException */ public function archive($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->cardServiceValidator->check(compact('id')); + $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -523,9 +464,8 @@ class CardService { * @throws BadRequestException */ public function unarchive($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->cardServiceValidator->check(compact('id')); + $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -552,13 +492,8 @@ class CardService { * @throws BadRequestException */ public function assignLabel($cardId, $labelId) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } + $this->cardServiceValidator->check(compact('cardId', 'labelId')); - if (is_numeric($labelId) === false) { - throw new BadRequestException('label id must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $cardId)) { @@ -586,13 +521,8 @@ class CardService { * @throws BadRequestException */ public function removeLabel($cardId, $labelId) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } + $this->cardServiceValidator->check(compact('cardId', 'labelId')); - if (is_numeric($labelId) === false) { - throw new BadRequestException('label id must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $cardId)) { diff --git a/lib/Service/LabelService.php b/lib/Service/LabelService.php index f4c95fb6..61ed58f0 100644 --- a/lib/Service/LabelService.php +++ b/lib/Service/LabelService.php @@ -29,6 +29,7 @@ use OCA\Deck\Db\Acl; use OCA\Deck\Db\LabelMapper; use OCA\Deck\StatusException; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\LabelServiceValidator; class LabelService { @@ -40,12 +41,21 @@ class LabelService { private $boardService; /** @var ChangeHelper */ private $changeHelper; - - public function __construct(LabelMapper $labelMapper, PermissionService $permissionService, BoardService $boardService, ChangeHelper $changeHelper) { + /** @var LabelServiceValidator */ + private LabelServiceValidator $labelServiceValidator; + + public function __construct( + LabelMapper $labelMapper, + PermissionService $permissionService, + BoardService $boardService, + ChangeHelper $changeHelper, + LabelServiceValidator $labelServiceValidator + ) { $this->labelMapper = $labelMapper; $this->permissionService = $permissionService; $this->boardService = $boardService; $this->changeHelper = $changeHelper; + $this->labelServiceValidator = $labelServiceValidator; } /** @@ -76,17 +86,7 @@ class LabelService { * @throws BadRequestException */ public function create($title, $color, $boardId) { - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->labelServiceValidator->check(compact('title', 'color', 'boardId')); $this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE); @@ -119,9 +119,7 @@ class LabelService { * @throws BadRequestException */ public function delete($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('label id must be a number'); - } + $this->labelServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE); if ($this->boardService->isArchived($this->labelMapper, $id)) { @@ -144,17 +142,7 @@ class LabelService { * @throws BadRequestException */ public function update($id, $title, $color) { - if (is_numeric($id) === false) { - throw new BadRequestException('label id must be a number'); - } - - if ($title === false || $title === null || $title === "") { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } + $this->labelServiceValidator->check(compact('title', 'color', 'id')); $this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE); diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 1e8bfc56..d41c00de 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -39,6 +39,7 @@ use OCA\Deck\Db\StackMapper; use OCA\Deck\Model\CardDetails; use OCA\Deck\NoPermissionException; use OCA\Deck\StatusException; +use OCA\Deck\Validators\StackServiceValidator; use Psr\Log\LoggerInterface; class StackService { @@ -54,6 +55,7 @@ class StackService { private ActivityManager $activityManager; private ChangeHelper $changeHelper; private LoggerInterface $logger; + private StackServiceValidator $stackServiceValidator; public function __construct( StackMapper $stackMapper, @@ -67,7 +69,8 @@ class StackService { AttachmentService $attachmentService, ActivityManager $activityManager, ChangeHelper $changeHelper, - LoggerInterface $logger + LoggerInterface $logger, + StackServiceValidator $stackServiceValidator ) { $this->stackMapper = $stackMapper; $this->boardMapper = $boardMapper; @@ -81,6 +84,7 @@ class StackService { $this->activityManager = $activityManager; $this->changeHelper = $changeHelper; $this->logger = $logger; + $this->stackServiceValidator = $stackServiceValidator; } private function enrichStackWithCards($stack, $since = -1) { @@ -218,17 +222,7 @@ class StackService { * @throws BadRequestException */ public function create($title, $boardId, $order) { - if ($title === false || $title === null || mb_strlen($title) === 0) { - throw new BadRequestException('title must be provided'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->stackServiceValidator->check(compact('title', 'boardId', 'order')); $this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE); if ($this->boardService->isArchived(null, $boardId)) { @@ -291,21 +285,7 @@ class StackService { * @throws BadRequestException */ public function update($id, $title, $boardId, $order, $deletedAt) { - if (is_numeric($id) === false) { - throw new BadRequestException('stack id must be a number'); - } - - if ($title === false || $title === null || mb_strlen($title) === 0) { - throw new BadRequestException('title must be provided'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } + $this->stackServiceValidator->check(compact('id', 'title', 'boardId', 'order')); $this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE); @@ -341,13 +321,7 @@ class StackService { * @throws BadRequestException */ public function reorder($id, $order) { - if (is_numeric($id) === false) { - throw new BadRquestException('id must be a number'); - } - - if ($order === false || $order === null) { - throw new BadRequestException('order must be provided'); - } + $this->stackServiceValidator->check(compact('id', 'order')); $this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE); $stackToSort = $this->stackMapper->find($id); diff --git a/lib/Validators/AssignmentServiceValidator.php b/lib/Validators/AssignmentServiceValidator.php new file mode 100644 index 00000000..42980e16 --- /dev/null +++ b/lib/Validators/AssignmentServiceValidator.php @@ -0,0 +1,37 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class AssignmentServiceValidator extends BaseValidator { + public function rules() { + return [ + 'cardId' => ['numeric'], + 'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'], + ]; + } +} diff --git a/lib/Validators/AttachmentServiceValidator.php b/lib/Validators/AttachmentServiceValidator.php new file mode 100644 index 00000000..c3f6ae77 --- /dev/null +++ b/lib/Validators/AttachmentServiceValidator.php @@ -0,0 +1,37 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class AttachmentServiceValidator extends BaseValidator { + public function rules() { + return [ + 'cardId' => ['numeric'], + 'type' => ['not_empty', 'not_null', 'not_false'], + 'data' => ['not_empty', 'not_null', 'not_false', 'max:255'], + ]; + } +} diff --git a/lib/Validators/BaseValidator.php b/lib/Validators/BaseValidator.php new file mode 100644 index 00000000..5601a84a --- /dev/null +++ b/lib/Validators/BaseValidator.php @@ -0,0 +1,182 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +use Exception; +use OCA\Deck\BadRequestException; + +abstract class BaseValidator { + + /** + * @return array + */ + abstract public function rules(); + + /** + * Validate given entries + * + * @param array $data + * @return void + * @throws BadRequestException + */ + private function validate($data) { + $rules = $this->rules(); + + foreach ($data as $field => $value) { + $field_rule = $rules[$field]; + + if (is_array($field_rule)) { + foreach ($field_rule as $rule) { + // The format for specifying validation rules and parameters follows an + // easy {rule}:{parameters} formatting convention. For instance the + // rule "Max:3" states that the value may only be three letters. + if (strpos($rule, ':') !== false) { + [$rule, $parameter] = explode(':', $rule, 2); + if (!$this->{$rule}($value, $parameter)) { + throw new BadRequestException( + $this->getErrorMessage($rule, $field, $parameter)); + } + } else { + if (!$this->{$rule}($value)) { + throw new BadRequestException( + $field . ' must be provided and must be '. str_replace("_", " ", $rule)); + } + } + } + } + + if (is_callable($field_rule) && !$field_rule($value)) { + throw new BadRequestException($field . ' must be provided'); + } + } + } + + /** + * @param array $data + * @return void + * @throws BadRequestException + */ + public function check(array $data) { + $this->validate($data); + } + + /** + * @param $value + * @return bool + */ + private function numeric($value): bool { + return is_numeric($value); + } + + /** + * @param $value + * @return bool + */ + private function bool($value): bool { + return is_bool($value); + } + + /** + * @param $value + * @return bool + */ + private function not_false($value): bool { + return ($value !== false) && ($value !== 'false'); + } + + /** + * @param $value + * @return bool + */ + private function not_null($value): bool { + return !is_null($value); + } + + /** + * @param $value + * @return bool + */ + private function not_empty($value): bool { + return !empty($value); + } + + /** + * @throws Exception + */ + private function max($value, $limit): bool { + if (!$limit || !is_numeric($limit)) { + throw new Exception("Validation rule max requires at least 1 parameter. " . json_encode($limit)); + } + return $this->getSize($value) <= $limit; + } + + /** + * @throws Exception + */ + private function min($value, $limit): bool { + if (!$limit || !is_numeric($limit)) { + throw new Exception("Validation rule max requires at least 1 parameter."); + } + return $this->getSize($value) >= $limit; + } + + /** + * Get the size of an attribute. + * + * @param mixed $value + * @return int + */ + protected function getSize($value): int { + // This method will determine if the attribute is a number or string and + // return the proper size accordingly. If it is a number, then number itself + // is the size. + if (is_int($value)) { + return $value; + } elseif (is_array($value)) { + return count($value); + } + + return mb_strlen($value ?? ''); + } + + /** + * @param $rule + * @param $field + * @param $parameter + * @return string + */ + protected function getErrorMessage($rule, $field, $parameter = null): string { + if (in_array($rule, ['max', 'min'])) { + return $rule === 'max' + ? $field . ' cannot be longer than '. $parameter . ' characters ' + : $field . ' must be at least '. $parameter . ' characters long '; + } + + return $field . ' must be provided and must be '. str_replace("_", " ", $rule); + } +} diff --git a/lib/Validators/BoardServiceValidator.php b/lib/Validators/BoardServiceValidator.php new file mode 100644 index 00000000..f5d58ecb --- /dev/null +++ b/lib/Validators/BoardServiceValidator.php @@ -0,0 +1,47 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class BoardServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'boardId' => ['numeric'], + 'type' => ['numeric'], + 'mapper' => ['not_empty', 'not_null', 'not_false'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'color' => ['not_empty', 'not_null', 'not_false', 'max:6'], + 'participant' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'edit' => ['not_null'], + 'share' => ['not_null'], + 'manage' => ['not_null'], + 'archived' => ['bool'] + ]; + } +} diff --git a/lib/Validators/CardServiceValidator.php b/lib/Validators/CardServiceValidator.php new file mode 100644 index 00000000..0417d996 --- /dev/null +++ b/lib/Validators/CardServiceValidator.php @@ -0,0 +1,44 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class CardServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:255'], + 'cardId' => ['numeric'], + 'stackId' => ['numeric'], + 'boardId' => ['numeric'], + 'labelId' => ['numeric'], + 'type' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'order' => ['numeric'], + 'owner' => ['not_empty', 'not_null', 'not_false', 'max:64'], + ]; + } +} diff --git a/lib/Validators/LabelServiceValidator.php b/lib/Validators/LabelServiceValidator.php new file mode 100644 index 00000000..c350cb76 --- /dev/null +++ b/lib/Validators/LabelServiceValidator.php @@ -0,0 +1,39 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + + declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class LabelServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'boardId' => ['numeric', 'not_null'], + 'color' => ['not_empty', 'not_null', 'not_false', 'max:6'] + ]; + } +} diff --git a/lib/Validators/StackServiceValidator.php b/lib/Validators/StackServiceValidator.php new file mode 100644 index 00000000..c32e7ac7 --- /dev/null +++ b/lib/Validators/StackServiceValidator.php @@ -0,0 +1,39 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * @author Maxence Lange <maxence@artificial-owl.com> + * @author Luka Trovic <luka.trovic@nextcloud.com> + * + * @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/>. + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class StackServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'boardId' => ['numeric', 'not_null'], + 'order' => ['numeric', 'not_null'] + ]; + } +} |