diff --git a/lib/Controller/Errors.php b/lib/Controller/Errors.php new file mode 100644 index 0000000..ea25fe7 --- /dev/null +++ b/lib/Controller/Errors.php @@ -0,0 +1,25 @@ +notFoundResponse($e); + } + } + + private function notFoundResponse(NotFoundException $e) { + $response = ['error' => get_class($e), 'message' => $e->getMessage()]; + return new JSONResponse($response, Http::STATUS_NOT_FOUND); + } +} \ No newline at end of file diff --git a/lib/Dav/SubscriptionManagementPlugin.php b/lib/Dav/SubscriptionManagementPlugin.php index 4eb9de1..f15dd62 100644 --- a/lib/Dav/SubscriptionManagementPlugin.php +++ b/lib/Dav/SubscriptionManagementPlugin.php @@ -29,7 +29,7 @@ namespace OCA\DavPush\Dav; use OCA\DavPush\Transport\TransportManager; use OCA\DavPush\Db\Subscription; -use OCA\DavPush\Db\SubscriptionMapper; +use OCA\DavPush\Service\SubscriptionService; use OCP\IUserSession; use OCP\IURLGenerator; @@ -60,7 +60,7 @@ class SubscriptionManagementPlugin extends ServerPlugin { private IUserSession $userSession, private TransportManager $transportManager, private IURLGenerator $URLGenerator, - private SubscriptionMapper $subscriptionMapper, + private SubscriptionService $subscriptionService, private $userId, ) { } @@ -100,7 +100,7 @@ class SubscriptionManagementPlugin extends ServerPlugin { $subscriptionType = ""; $subscriptionOptions = []; - $subscriptionExpires = False; + $subscriptionExpires = 0; foreach($parameters as $parameter) { if($parameter["name"] == self::PUSH_SUBSCRIPTION && !$subscriptionParameterIncluded) { @@ -112,8 +112,8 @@ class SubscriptionManagementPlugin extends ServerPlugin { } else { $errors[] = "only one subscription allowed"; } - } elseif($parameter["name"] == self::PUSH_EXPIRES && !$subscriptionExpires) { - $subscriptionExpires = \DateTime::createFromFormat(self::IMF_FIXDATE_FORMAT, $parameter["value"]); + } elseif($parameter["name"] == self::PUSH_EXPIRES && $subscriptionExpires === 0) { + $subscriptionExpires = \DateTime::createFromFormat(self::IMF_FIXDATE_FORMAT, $parameter["value"])->getTimestamp(); } } @@ -148,18 +148,7 @@ class SubscriptionManagementPlugin extends ServerPlugin { $response->setStatus($responseStatus); // create subscription entry in db - $subscription = new Subscription(); - $subscription->setUserId($this->userId); - $subscription->setCollectionName($node->getName()); - $subscription->setTransport($subscriptionType); - $subscription->setCreationTimestamp(time()); - if(!$subscriptionExpires) { - $subscription->setExpirationTimestamp(0); - } else { - $subscription->setExpirationTimestamp($subscriptionExpires->getTimestamp()); - } - $subscription->setData(json_encode($data)); - $subscription = $this->subscriptionMapper->insert($subscription); + $subscription = $this->subscriptionService->create($this->userId, $node->getName(), $subscriptionType, $subscriptionExpires, $data); // generate default unsubscribe link, unless transport requested a custom url $unsubscribeLink = $unsubscribeLink ?? $this->URLGenerator->getAbsoluteURL("/apps/dav_push/subscriptions/" . $subscription->getId()); diff --git a/lib/Db/SubscriptionMapper.php b/lib/Db/SubscriptionMapper.php index 9cddbdc..ab40678 100644 --- a/lib/Db/SubscriptionMapper.php +++ b/lib/Db/SubscriptionMapper.php @@ -34,18 +34,31 @@ class SubscriptionMapper extends QBMapper { } /** - * @param string $userId * @param string $collectionName * @return Subscription[] */ - public function findAll(string $userId, string $collectionName): array { + public function findAll(string $collectionName): array { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from(self::TABLENAME) - ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))) - ->andWhere($qb->expr()->eq('collection_name', $qb->createNamedParameter($collectionName))); + ->where($qb->expr()->eq('collection_name', $qb->createNamedParameter($collectionName))); + + return $this->findEntities($qb); + } + + /** + * @param string $userId + * @return Subscription[] + */ + public function findAllByUser(string $userId): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from(self::TABLENAME) + ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))); return $this->findEntities($qb); } diff --git a/lib/Errors/NotFoundException.php b/lib/Errors/NotFoundException.php new file mode 100644 index 0000000..c7aa408 --- /dev/null +++ b/lib/Errors/NotFoundException.php @@ -0,0 +1,6 @@ +getCalendarData()['uri']; - $subscriptions = $this->subscriptionMapper->findAll($this->userId, $collectionName); + $subscriptions = $this->subscriptionService->findAll($collectionName); foreach($subscriptions as $subscription) { $transport = $this->transportManager->getTransport($subscription->getTransport()); try { - $transport->notify($this->userId, $collectionName, json_decode($subscription->getData(), True)); + $transport->notify($subscription->getUserId(), $collectionName, json_decode($subscription->getData(), True)); } catch (Error $e) { $this->logger->error("transport " . $subscription->getTransport() . " failed to deliver notification to subscription " . $subscription->getId()); } diff --git a/lib/Service/SubscriptionService.php b/lib/Service/SubscriptionService.php new file mode 100644 index 0000000..3dd770c --- /dev/null +++ b/lib/Service/SubscriptionService.php @@ -0,0 +1,86 @@ +mapper->findAll($collectionName); + } + + public function findAllByUser(string $userId): array { + return $this->mapper->findAllByUser($userId); + } + + private function handleException(Exception $e): void { + if ($e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException) { + throw new SubscriptionNotFound($e->getMessage()); + } else { + throw $e; + } + } + + public function find(string $userId, int $id) { + try { + return $this->mapper->find($userId, $id); + } catch (Exception $e) { + $this->handleException($e); + } + } + + public function create(string $userId, string $collectionName, string $transport, int $expirationTimestamp, $data, ?int $creationTimestamp = null) { + $subscription = new Subscription(); + $subscription->setUserId($userId); + $subscription->setCollectionName($collectionName); + $subscription->setTransport($transport); + $subscription->setCreationTimestamp($creationTimestamp ?? time()); + $subscription->setExpirationTimestamp($expirationTimestamp); + $subscription->setData(json_encode($data)); + $subscription = $this->mapper->insert($subscription); + + return $subscription; + } + + public function update(string $userId, int $id, ?int $expirationTimestamp, mixed $data) { + try { + $subscription = $this->mapper->find($userId, $id); + + if (!is_null($expirationTimestamp)) { + $subscription->setExpirationTimestamp($expirationTimestamp); + } + + if (!is_null($data)) { + $subscription->setData(json_encode($data)); + } + + return $this->mapper->update($subscription); + } catch (Exception $e) { + $this->handleException($e); + } + } + + public function delete(string $userId, int $id) { + try { + $subscription = $this->mapper->find($userId, $id); + $this->mapper->delete($subscription); + return $subscription; + } catch (Exception $e) { + $this->handleException($e); + } + } +} \ No newline at end of file